1191 lines
29 KiB
Markdown
1191 lines
29 KiB
Markdown
---
|
||
categories:
|
||
- "[[Tools]]"
|
||
- "[[Documentation]]"
|
||
tags:
|
||
- agents
|
||
- ai-assistant
|
||
- development-workflow
|
||
- obsidian-vault
|
||
- knowledge-management
|
||
created: 2026-01-23
|
||
rating: 7
|
||
type: schema
|
||
---
|
||
|
||
# AGENTS.md - Obsidian Vault 智能代理指南
|
||
|
||
## 概述
|
||
|
||
本指南为在这个 Obsidian 知识库中工作的智能代理(AI Coding Agents)提供详细的操作规范、代码风格指南和工作流指导。确保所有代理能够高效协作,遵循统一的编码标准,并在 PARA + LLM Wiki 双层架构中正确组织知识。
|
||
|
||
> **目标:** 让 AI 代理像真正的开发团队成员一样高效工作,遵循最佳实践,保持代码质量和一致性。
|
||
|
||
**IMPORTANT:** 处理 Obsidian 笔记时,必须优先使用以下官方 Skills(来源:kepano/obsidian-skills)。
|
||
|
||
> |Skill|用途|何时用|
|
||
> |---|---|---|
|
||
> |`obsidian-cli`|CLI 命令(搜索、读写、任务、属性、插件开发)|**首选**,几乎所有 vault 操作|
|
||
> |`obsidian-markdown`|`.md` 笔记编写(frontmatter、wikilink、callout、embed)|创建/编辑笔记内容时|
|
||
> |`obsidian-bases`|`.base` 数据库视图(filters、formulas、views)|创建/编辑 Bases 文件时|
|
||
> |`json-canvas`|`.canvas` 图表(nodes、edges、groups)|创建/编辑 Canvas 文件时|
|
||
> |`defuddle`|网页→干净 Markdown(去导航/广告/杂讯)|处理 URL 时优先于 WebFetch|
|
||
>
|
||
> 使用 `skill` 工具加载对应 skill 后再执行操作。
|
||
---
|
||
|
||
### Obsidian CLI (v1.12.7+)
|
||
|
||
新版 CLI 使用独立二进制文件,响应更快。常用命令:
|
||
|
||
```bash
|
||
# 版本检查
|
||
obsidian version
|
||
|
||
# 日常操作
|
||
obsidian daily:read # 读取今日日记
|
||
obsidian daily:append content="- [ ] 新任务" # 添加任务
|
||
obsidian tasks todo limit=10 # 查看待办
|
||
|
||
# 文件操作
|
||
obsidian files total # 文件总数
|
||
obsidian search query="关键词" limit=5 # 搜索
|
||
obsidian tags sort=count counts # 标签统计
|
||
## 1. 仓库架构总览
|
||
|
||
本项目采用**双层知识管理模式**,结合 PARA 方法论和 LLM Wiki 模式:
|
||
|
||
```mermaid
|
||
graph TD
|
||
subgraph PARA["PARA 层(个人知识)"]
|
||
C[Categories/]
|
||
R[References/]
|
||
N[Notes/]
|
||
D[Daily/]
|
||
Cl[Clippings/]
|
||
T[Tags/]
|
||
end
|
||
|
||
subgraph Wiki["LLM Wiki 层(编译知识)"]
|
||
Wiki[wiki/]
|
||
Raw[raw/]
|
||
end
|
||
|
||
subgraph Infrastructure["基础设施"]
|
||
Templates[Templates/]
|
||
Attach[Attachments/]
|
||
Schema[AGENTS.md]
|
||
end
|
||
|
||
Ingest[新来源] --> Raw
|
||
Raw -->|Ingest 操作| Wiki
|
||
Wiki -->|归档| PARA
|
||
|
||
Wiki --> Schema
|
||
Schema --> Wiki
|
||
```
|
||
|
||
### 1.1 文件夹组织
|
||
|
||
| 文件夹 | 用途 | 文件格式 | 维护者 |
|
||
|--------|------|----------|--------|
|
||
| **PARA 层** | | | |
|
||
| | | | |
|
||
| `Categories/` | PARA 类别索引页面 | `Books.md`, `Movies.md` (复数) | 人类 |
|
||
| `References/` | 实体参考文件 | `Kevin Kelly.md`, `Obsidian.md` | 人类 + LLM |
|
||
| `Notes/` | 个人反思和分析 | `Evergreen notes…md` | 人类 |
|
||
| `Daily/` | 日常日记 | `2026-01-23.md` | 人类 |
|
||
| `Clippings/` | 网页摘录 | `Article Title.md` | 人类 |
|
||
| `Tags/` | 标签定义和索引 | `主题-ai.md`, `卡片-金句.md` | 人类 |
|
||
| | | | |
|
||
| **LLM Wiki 层** | | | |
|
||
| | | | |
|
||
| `wiki/` | LLM 编译维护的知识库 | `Concept.md`, `Person.md` | LLM |
|
||
| `raw/` | 不可变的原始来源 | `source.md` | 人类 |
|
||
| | | | |
|
||
| **基础设施** | | | |
|
||
| | | | |
|
||
| `Templates/` | 笔记和演示模板 | `*.md`, `*.css`, `*.base` | 人类 |
|
||
| `Attachments/` | 媒体文件 | 图片、PDF、视频 | 人类 |
|
||
| `markdown_output/` | 外部导入的内容 | `*.md` | 批量导入 |
|
||
| `AGENTS.md` | **Schema:代理操作规范** | 本文件 | 人类 + LLM |
|
||
|
||
### 1.2 PARA 方法论
|
||
|
||
PARA 层用于组织**个人项目、领域、资源和归档**:
|
||
|
||
| 类型 | 说明 | 示例 |
|
||
|------|------|----------|
|
||
| **Projects** | 有明确目标和时间线的活跃项目 | `项目-卡片笔记实践`, `项目-论文1` |
|
||
| **Areas** | 持续关注的领域和责任 | `领域-山西`, `领域-自组网` |
|
||
| **Resources** | 未来参考的主题和兴趣 | Obsidian 笔记、AI 工具、参考材料 |
|
||
| **Archive** | 已完成的项目和不活跃内容 | 过去项目、归档资料 |
|
||
|
||
**注意事项**:
|
||
- PARA 层主要由人类维护,LLM 辅助
|
||
- LLM Wiki 的编译结果可以归档到 PARA 层(如 References/)
|
||
|
||
### 1.3 LLM Wiki 模式
|
||
|
||
LLM Wiki 层是**由 LLM 增量编译和维护的结构化知识库**:
|
||
|
||
| 层级 | 位置 | 职责 | 维护者 |
|
||
|------|------|------|--------|
|
||
| **Raw Sources** | `raw/` | 不可变的原始文档、文章、论文、数据文件 | 人类 |
|
||
| **Wiki** | `wiki/` | 摘要、实体页、概念页、比较、综合 | **LLM** |
|
||
| **Schema** | `AGENTS.md` | Wiki 结构约定、工作流规范 | 人类 + LLM |
|
||
|
||
**三种核心操作**:
|
||
1. **Ingest(摄入)**:将新来源编译到 wiki,更新 index 和 log
|
||
2. **Query(查询)**:搜索 wiki 页面并综合回答
|
||
3. **Lint(健康检查)**:检查矛盾、过时、孤立页面、缺失交叉引用
|
||
|
||
**索引与日志**:
|
||
- `wiki/index.md` - 内容目录,按类别组织(每次 ingest 更新)
|
||
- `wiki/log.md` - 时间线日志(grep 可解析的格式)
|
||
|
||
### 1.4 Frontmatter 规范
|
||
|
||
#### PARA 层(Categories, References, Clippings, Notes)
|
||
|
||
所有 PARA 内容笔记必须包含 YAML frontmatter:
|
||
|
||
```yaml
|
||
---
|
||
categories:
|
||
- "[[Books]]"
|
||
- "[[People]]"
|
||
tags:
|
||
- books
|
||
- people
|
||
- reference
|
||
created: 2026-01-23
|
||
rating: 5
|
||
author: []
|
||
topics: []
|
||
para: []
|
||
---
|
||
|
||
<!-- Added: 2026-04-07 -->
|
||
## Obsidian Frontmatter 布尔值规范
|
||
|
||
在 Obsidian 笔记的 YAML frontmatter 中,布尔值 `true`/`false` 会被 Obsidian 识别为 checkbox 类型属性。为避免此问题,所有布尔值属性必须用引号包裹为字符串:
|
||
|
||
- ✅ `marp: "true"`
|
||
- ✅ `paginate: "true"`
|
||
- ❌ `marp: true`(Obsidian 会将其显示为 checkbox)
|
||
- ❌ `paginate: true`(同上)
|
||
|
||
此规范适用于所有通过 LLM 生成或修改的 Obsidian 笔记。HTML 注释中的指令(如 `<!-- paginate: true -->`)不受影响,保持原样。
|
||
|
||
## 内容开始
|
||
```
|
||
|
||
**Frontmatter 规则**:
|
||
- ✅ **Categories**:使用 wikilink 格式 `[[Category]]`,frontmatter 中用复数 `categories: [[Books]]`
|
||
- ✅ **Tags**:短横线连接、小写、无空格(例如:`#tag` 或 `ai/coding`)
|
||
- ✅ **Dates**:`YYYY-MM-DD` 格式
|
||
- ✅ **多值字段**:使用列表格式,即使单值也要加 `[]`(例如:`author: ["Kevin Kelly"]`)
|
||
- ✅ **空字段**:留空不写引号或 null(例如:`via: ""`)
|
||
- ✅ **分隔符**:YAML 后必须有空行 `---`,正文前也要有空行
|
||
|
||
#### LLM Wiki 层
|
||
|
||
Wiki 页面必须包含以下 frontmatter:
|
||
|
||
```yaml
|
||
---
|
||
categories:
|
||
- "[[LLM Wiki]]" # ✅ 必须包含
|
||
tags:
|
||
- wiki # ✅ 必须包含
|
||
- {tag1}
|
||
- {tag2}
|
||
created: {YYYY-MM-DD}
|
||
source: "[[{source-file}]]" # ✅ 必须指向 raw 来源
|
||
type: concept | entity | tool | index | log # ✅ 必须指定类型
|
||
aliases: # 可选
|
||
- {alias1}
|
||
- {alias2}
|
||
marp: "true" # Marp 演示文稿专用
|
||
---
|
||
```
|
||
|
||
**字段说明**:
|
||
|
||
| 字段 | 必填 | PARA 层 | Wiki 层 | 说明 |
|
||
|------|------|---------|---------|------|
|
||
| `categories` | ✅ | `[[Category]]` | `[[LLM Wiki]]` | 类别 |
|
||
| `tags` | ✅ | `{tag}` | `wiki`, `{tag}` | 标签 |
|
||
| `created` | ✅ | `YYYY-MM-DD` | `YYYY-MM-DD` | 创建日期 |
|
||
| `source` | ❌ | 可选 | ✅ 必填 | Wiki 层必须指向 raw 来源 |
|
||
| `type` | ❌ | 可选 | ✅ 必填 | Wiki 层必须指定页面类型 |
|
||
| `aliases` | ❌ | 可选 | 可选 | 替代名称列表 |
|
||
| `marp` | ❌ | 可选 | 可选 | 演示文稿标识,必须用引号 |
|
||
|
||
---
|
||
|
||
## 2. Wiki 工作流
|
||
|
||
### 2.1 Ingest(摄入)操作
|
||
|
||
当收到新来源时,按以下流程处理:
|
||
|
||
```mermaid
|
||
graph LR
|
||
A[收到新来源] --> B[存入 raw/]
|
||
B --> C[读取并分析关键要点]
|
||
C --> D[创建/更新 Wiki 页面]
|
||
D --> E[更新 index.md]
|
||
E --> F[追加 log.md 条目]
|
||
F --> G[完成]
|
||
```
|
||
|
||
**详细步骤**:
|
||
|
||
1. **读取来源**
|
||
```bash
|
||
# 来源存入 raw/ 目录
|
||
raw/source-name.md
|
||
```
|
||
|
||
2. **创建 Wiki 页面**
|
||
- 根据内容类型创建相应页面:
|
||
- **概念页**:`wiki/概念名称.md` - 理论、方法论、模式
|
||
- **实体页**:`wiki/人物姓名.md` - 人物、公司、组织
|
||
- **工具页**:`wiki/工具名称.md` - 软件、框架、工具
|
||
- **参考页**:`wiki/主题-子主题.md` - 详细文档、教程
|
||
|
||
3. **更新 index.md**
|
||
```yaml
|
||
## 概览
|
||
|
||
| 指标 | 值 |
|
||
|------|-----|
|
||
| 来源数 | {更新数字} |
|
||
| Wiki 页面数 | {更新数字} |
|
||
|
||
```
|
||
|
||
4. **追加 log.md**
|
||
```markdown
|
||
## [YYYY-MM-DD] ingest | {来源标题}
|
||
|
||
**来源**: {来源链接或文件路径}
|
||
|
||
**操作**:
|
||
- 操作 1
|
||
- 操作 2
|
||
|
||
**涉及页面**: N 个新页面,M 个更新页面
|
||
|
||
**关键要点**:
|
||
- 要点 1
|
||
- 要点 2
|
||
```
|
||
|
||
**示例**:参考 `wiki/log.md` 中的历史记录
|
||
|
||
### 2.2 Query(查询)操作
|
||
|
||
当用户对 Wiki 提问时:
|
||
|
||
1. 搜索相关页面(使用 grep 或 qmd)
|
||
2. 综合多页面的信息
|
||
3. 如果发现新的见解,**将回答归档为新 Wiki 页面**
|
||
4. 更新 index 和 log
|
||
|
||
> **原则**:好的回答应该成为 Wiki 的一部分,让探索像摄入一样持续积累。
|
||
|
||
### 2.3 Lint(健康检查)
|
||
|
||
定期执行健康检查:
|
||
|
||
1. **检查矛盾** - 搜索冲突声明
|
||
2. **检查过时** - 标记陈旧信息
|
||
3. **检查孤立页面** - 无入站链接的页面
|
||
4. **检查缺失概念** - 需要创建但尚未创建的页面
|
||
5. **检查交叉引用** - 确保相关页面互相链接
|
||
|
||
```bash
|
||
# 示例命令
|
||
grep -r "TODO\|FIXME\|过时\|矛盾" wiki/
|
||
grep -r "\[\[" wiki/ | grep -v "md:" | sort | uniq -c | sort -rn | head -20
|
||
```
|
||
|
||
### 2.4 Wiki 页面模板
|
||
|
||
参考 `Templates/Wiki Page Template.md`:
|
||
|
||
**概念页面**:
|
||
```markdown
|
||
---
|
||
categories:
|
||
- "[[LLM Wiki]]"
|
||
tags:
|
||
- wiki
|
||
- {tag1}
|
||
- {tag2}
|
||
created: {YYYY-MM-DD}
|
||
source: "[[{source-file}]]"
|
||
type: concept
|
||
aliases:
|
||
- {alias1}
|
||
---
|
||
|
||
# {概念名称}
|
||
|
||
> **一句话定义**:{核心定义}
|
||
|
||
## 定义
|
||
|
||
{概念的详细定义和解释}
|
||
|
||
## 关键要点
|
||
|
||
- 要点 1
|
||
- 要点 2
|
||
- 要点 3
|
||
|
||
## 与其他概念的关系
|
||
|
||
- [[相关概念1]] — {关系说明}
|
||
- [[相关概念2]] — {关系说明}
|
||
|
||
## 来源
|
||
|
||
- [[source]] — 来源描述
|
||
```
|
||
|
||
**实体页面**:
|
||
```markdown
|
||
---
|
||
categories:
|
||
- "[[LLM Wiki]]"
|
||
- "[[People]]"
|
||
tags:
|
||
- wiki
|
||
- people
|
||
- {domain}
|
||
created: {YYYY-MM-DD}
|
||
source: "[[{source-file}]]"
|
||
type: entity
|
||
aliases:
|
||
- {alias}
|
||
---
|
||
|
||
# {人物姓名}
|
||
|
||
{一句话简介}
|
||
|
||
## 身份
|
||
|
||
| 属性 | 值 |
|
||
|------|-----|
|
||
| 领域 | {领域} |
|
||
| 知名身份 | {身份} |
|
||
|
||
## 主要贡献
|
||
|
||
- 贡献 1
|
||
- 贡献 2
|
||
|
||
## 与本 Wiki 相关
|
||
|
||
{此人与 wiki 内容的关联}
|
||
|
||
## 来源
|
||
|
||
- [[source]] — 来源描述
|
||
```
|
||
|
||
**工具页面**:
|
||
```markdown
|
||
---
|
||
categories:
|
||
- "[[LLM Wiki]]"
|
||
tags:
|
||
- wiki
|
||
- tool
|
||
- {category}
|
||
created: {YYYY-MM-DD}
|
||
source: "[[{source-file}]]"
|
||
type: tool
|
||
aliases:
|
||
- {alias}
|
||
---
|
||
|
||
# {工具名称}
|
||
|
||
> **一句话描述**
|
||
|
||
## 基本信息
|
||
|
||
| 属性 | 值 |
|
||
|------|-----|
|
||
| 仓库 | {URL} |
|
||
| 类型 | {类型} |
|
||
|
||
## 在 LLM Wiki 中的角色
|
||
|
||
{工具在 wiki 工作流中的作用}
|
||
|
||
## 来源
|
||
|
||
- [[source]] — 来源描述
|
||
```
|
||
|
||
---
|
||
|
||
## 3. Marp 演示文稿工作流
|
||
|
||
### 3.1 Marp 基础知识
|
||
|
||
Marp 是用 Markdown 编写演示文稿的生态系统。本知识库使用 Marp 创建幻灯片。
|
||
|
||
**核心概念**:
|
||
- **Marpit** - 框架层,定义指令解析和转换规则
|
||
- **Marp Core** - 引擎层,实现 Marpit 接口
|
||
- **Marp CLI** - 命令行工具,导出 HTML/PDF/PPTX
|
||
- **Obsidian Marp 插件** - 在 Obsidian 中预览和导出
|
||
|
||
### 3.2 Frontmatter 指令
|
||
|
||
Marp 演示文稿必须包含 Marp frontmatter:
|
||
|
||
```yaml
|
||
---
|
||
marp: "true" # ✅ 必须用引号包裹
|
||
theme: gaia # 主题:default, uncover, gaia
|
||
paginate: "true" # ✅ 必须用引号包裹
|
||
style: |
|
||
/* 自定义样式 */
|
||
section {
|
||
background: linear-gradient(to bottom, #1a1a2e, #16213e);
|
||
color: white;
|
||
}
|
||
---
|
||
|
||
<!-- _class: cover -->
|
||
# 标题页
|
||
|
||
<!-- _class: dark -->
|
||
# 深色页
|
||
```
|
||
|
||
**全局指令**(frontmatter 中):
|
||
- `marp: "true"` - 启用 Marp
|
||
- `theme: default/uncover/gaia` - 选择主题
|
||
- `paginate: "true"` - 显示页码
|
||
- `style: |` - 自定义 CSS
|
||
|
||
**局部指令**(注释中):
|
||
- `<!-- _class: cover -->` - 封面页样式
|
||
- `<!-- _class: dark -->` - 深色背景
|
||
- `<!-- _class: cols-2 -->` - 两栏布局
|
||
- `<!-- _paginate: false -->` - 当前页不显示页码
|
||
|
||
**自定义主题**:
|
||
- 主题文件存放在 `Templates/MarpTheme/`
|
||
- 格式:`theme-name.css`
|
||
- 使用后需重启 Obsidian
|
||
- 在 frontmatter 中引用:`theme: theme-name`
|
||
|
||
### 3.3 自定义主题示例
|
||
|
||
**University Blue 主题** (`Templates/MarpTheme/university-blue.css`):
|
||
|
||
```css
|
||
/* @theme university-blue */
|
||
|
||
@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@400;700&display=swap');
|
||
|
||
:root {
|
||
--primary-color: #1a365d; /* 学术蓝 */
|
||
--secondary-color: #2b6cb0;
|
||
--accent-color: #4299e1;
|
||
--text-color: #1a202c;
|
||
--bg-color: #ffffff;
|
||
}
|
||
|
||
section {
|
||
background: var(--bg-color);
|
||
color: var(--text-color);
|
||
font-family: 'Noto Sans SC', sans-serif;
|
||
}
|
||
|
||
h1, h2, h3 {
|
||
color: var(--primary-color);
|
||
}
|
||
|
||
/* 封面页 */
|
||
section.cover {
|
||
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
|
||
color: white;
|
||
}
|
||
|
||
/* 两栏布局 */
|
||
.cols-2 {
|
||
display: grid;
|
||
grid-template-columns: 1fr 1fr;
|
||
gap: 2rem;
|
||
}
|
||
```
|
||
|
||
**使用方式**:
|
||
```yaml
|
||
---
|
||
marp: "true"
|
||
theme: university-blue
|
||
paginate: "true"
|
||
---
|
||
```
|
||
|
||
### 3.4 Marp 页面类型
|
||
|
||
| 类型 | 指令 | 用途 | 示例 |
|
||
|------|------|------|------|
|
||
| **封面页** | `<!-- _class: cover -->` | 标题、作者、日期 | 论文首页、报告封面 |
|
||
| **过渡页** | `<!-- _class: trans -->` | 章节分隔 | 章节标题页 |
|
||
| **深色页** | `<!-- _class: dark -->` | 强调、对比 | 数据可视化、代码块 |
|
||
| **两栏页** | `<!-- _class: cols-2 -->` | 左右对比 | 对比分析、并列说明 |
|
||
| **结束页** | `<!-- _class: ending -->` | 致谢、Q&A | 演示结尾 |
|
||
|
||
**完整示例**:参考 `wiki/示例-学校定制Marp演示.md`
|
||
|
||
### 3.5 导出方式
|
||
|
||
**Obsidian 插件**:
|
||
1. 打开 Marp 文件
|
||
2. 点击预览按钮(👁️)
|
||
3. 点击导出按钮(📥)
|
||
4. 选择格式:HTML / PDF / PPTX
|
||
|
||
**CLI 命令**:
|
||
```bash
|
||
# 导出 PDF
|
||
marp --pdf presentation.md -o output.pdf
|
||
|
||
# 导出 HTML
|
||
marp --html presentation.md -o output.html
|
||
|
||
# 导出 PPTX
|
||
marp --pptx presentation.md -o output.pptx
|
||
```
|
||
|
||
### 3.6 Marp 相关 Wiki 页面
|
||
|
||
| 页面 | 内容 | 来源 |
|
||
|------|------|------|
|
||
| `[[Marp]]` | 概念总览 | marp-guide |
|
||
| `[[Marp 指令语法]]` | 指令系统完整参考 | marp-guide |
|
||
| `[[Marp 主题与样式]]` | 内置主题、CSS 自定义 | marp-guide |
|
||
| `[[Marp 导出]]` | HTML/PDF/PPTX 导出方式 | marp-guide |
|
||
| `[[Obsidian Marp 插件]]` | Obsidian 集成 | marp-guide |
|
||
| `[[Marp 主题推荐]]` | GitHub 社区主题合集 | marp-themes |
|
||
| `[[示例-学校定制Marp演示]]` | 学校定制蓝主题演示 | marp-themes |
|
||
|
||
---
|
||
|
||
## 4. 构建与测试命令
|
||
|
||
### 4.1 可用命令
|
||
|
||
AI 代理可使用以下命令进行构建和测试:
|
||
|
||
| 命令 | 功能 | 使用场景 | 示例 |
|
||
|------|--------|----------|--------|
|
||
| **bun run dev** | 启动开发服务器 | 本地开发时热重载 |
|
||
| **bun run build** | 构建生产版本 | CI/CD 环境构建 |
|
||
| **bun run lint** | 运行代码检查 | 确保 ESLint 规范 |
|
||
| **bun test** | 运行单元测试 | Jest/Vitest 测试套件 |
|
||
| **bun run test:unit** | 单元测试 | `测试特定模块` |
|
||
| **bun run test:e2e** | E2E 测试 | `集成测试` |
|
||
| **bun run test:integration** | 集成测试 | 端到端测试 |
|
||
| **bun run test:coverage** | 测试覆盖率 | 生成覆盖率报告 |
|
||
| **bun run type-check** | 类型检查 | TypeScript 类型验证 |
|
||
| **pytest** | Python 测试 | 后端测试时使用 |
|
||
|
||
### 4.2 命令使用规范
|
||
|
||
```markdown
|
||
## 启动开发服务器
|
||
|
||
# 推荐方式
|
||
bun run dev
|
||
|
||
# 禁止方式
|
||
bun --bun run dev
|
||
|
||
# 或者使用 oh-my-opencode 的 pty_spawn
|
||
pty_spawn:
|
||
command: "bun"
|
||
args: ["run", "dev"],
|
||
title: "Dev Server",
|
||
notifyOnExit: true
|
||
```
|
||
|
||
```markdown
|
||
## 运行测试
|
||
|
||
# 单个测试
|
||
bun test path/to/test.spec.ts
|
||
|
||
# 带详细输出
|
||
bun test --reporter=verbose path/to/test.spec.ts
|
||
|
||
# 运行特定测试
|
||
bun test path/to/test.spec.ts -t "Authentication Flow"
|
||
|
||
# 生成覆盖率报告
|
||
bun run test:coverage --reporter=text --reporter=lcov
|
||
```
|
||
|
||
```markdown
|
||
## 类型检查
|
||
|
||
# TypeScript 类型检查
|
||
bun run type-check
|
||
|
||
# 或配合 TSC
|
||
bunx tsc --noEmit
|
||
```
|
||
|
||
### 4.3 测试最佳实践
|
||
|
||
#### 原则 1:快速失败(Fail Fast)
|
||
|
||
```markdown
|
||
# 单元测试应该快速执行(< 2 分钟)
|
||
- 快速发现明显问题
|
||
- 避免测试中的网络请求
|
||
- 使用 mock 数据隔离依赖
|
||
|
||
**适用场景:**
|
||
- 验证核心业务逻辑
|
||
- 测试纯函数组件
|
||
```
|
||
|
||
#### 原则 2:测试隔离
|
||
|
||
```markdown
|
||
# 每个测试文件应该能够独立运行
|
||
- 不依赖其他测试的状态
|
||
- 使用独立的测试数据库或 mock 服务
|
||
- 清理测试后的资源
|
||
|
||
**实现方式:**
|
||
```typescript
|
||
// 每个测试文件使用独立的 beforeEach/afterEach
|
||
import { beforeEach, afterEach } from '@testing-library/react';
|
||
|
||
describe('UserService', () => {
|
||
beforeEach(() => {
|
||
// 清理或初始化每个测试前的状态
|
||
userService = new UserService();
|
||
});
|
||
|
||
afterEach(() => {
|
||
// 清理每个测试后的资源
|
||
userService.dispose();
|
||
});
|
||
|
||
it('should create user', () => {
|
||
// 测试代码...
|
||
});
|
||
});
|
||
```
|
||
```
|
||
|
||
#### 原则 3:描述性测试名称
|
||
|
||
```markdown
|
||
# 测试名称应该清晰描述测试意图和场景
|
||
|
||
describe('Authentication Flow', () => {
|
||
it('should authenticate user with valid credentials', () => { });
|
||
it('should reject invalid credentials', () => { });
|
||
it('should handle network errors gracefully', () => { });
|
||
});
|
||
```
|
||
|
||
**避免:**
|
||
```markdown
|
||
// ❌ 避免模糊名称
|
||
it('test', () => {});
|
||
|
||
// ✅ 使用描述性名称
|
||
it('should authenticate user with valid credentials', () => {});
|
||
```
|
||
|
||
#### 原则 4:测试覆盖率目标
|
||
|
||
```markdown
|
||
# 设定测试覆盖率目标(建议 80% 以上)
|
||
|
||
# package.json 配置
|
||
{
|
||
"scripts": {
|
||
"test": "vitest run --coverage",
|
||
"test:coverage": "vitest run --coverage --reporter=json"
|
||
},
|
||
|
||
"coverage": {
|
||
"statements": 80,
|
||
"branches": 80,
|
||
"functions": 80,
|
||
"lines": 80
|
||
}
|
||
}
|
||
```
|
||
|
||
### 4.4 Lint 与格式化命令
|
||
|
||
```markdown
|
||
## ESLint
|
||
|
||
# 运行 ESLint
|
||
bun run lint
|
||
|
||
# 修复问题
|
||
bun run lint --fix
|
||
|
||
# 检查特定文件
|
||
bun run lint path/to/component.ts
|
||
|
||
# 生成报告
|
||
bun run lint --format json --output-file eslint-report.json
|
||
|
||
## Prettier
|
||
|
||
# 格式化代码
|
||
bun run format
|
||
|
||
# 检查格式
|
||
bun run format --check
|
||
|
||
# 格式化特定文件
|
||
bun run format path/to/component.ts
|
||
```
|
||
|
||
### 4.5 命令执行优先级
|
||
|
||
```markdown
|
||
## 开发工作流中的命令使用优先级
|
||
|
||
| 优先级 | 命令类型 | 说明 |
|
||
|--------|-----------|--------|
|
||
| **高** | 开发服务器启动/重启 | `bun run dev`(常用) |
|
||
| **高** | 类型检查 | `bun run type-check`(快速验证) |
|
||
| **中** | Lint/格式化 | `bun run lint`, `bun run format`(定期执行) |
|
||
| **中** | 单元测试 | `bun test`(开发过程中) |
|
||
| **低** | 集成测试 | `bun run test:integration`(PR 前或合并前) |
|
||
| **低** | E2E/覆盖率测试 | `bun run test:e2e`(定期执行) |
|
||
| **低** | 文档生成 | 手动生成文档 |
|
||
```
|
||
|
||
---
|
||
|
||
## 5. 代码风格指南
|
||
|
||
### 5.1 TypeScript 编码规范
|
||
|
||
#### 5.1.1 命名约定
|
||
|
||
```typescript
|
||
// ✅ 组件和类名:PascalCase
|
||
class UserService { }
|
||
interface UserProfile { }
|
||
|
||
// ✅ 函数和变量:camelCase
|
||
function getUserById() { }
|
||
const userId = 0;
|
||
const userProfile: UserProfile;
|
||
|
||
// ❌ 避免缩写
|
||
function getusr() { }
|
||
|
||
// ✅ 使用描述性名称
|
||
function authenticateUser() { }
|
||
|
||
// ✅ 常量:UPPER_SNAKE_CASE
|
||
const API_BASE_URL = 'https://api.example.com';
|
||
const MAX_RETRIES = 3;
|
||
|
||
// ❌ 避免单字母变量
|
||
const a = 1;
|
||
const n = userId;
|
||
```
|
||
|
||
#### 5.1.2 类型定义
|
||
|
||
```typescript
|
||
// ✅ 使用明确的类型定义
|
||
interface ApiResponse<T> {
|
||
data: T;
|
||
error?: string;
|
||
status: number;
|
||
}
|
||
|
||
// ✅ 使用泛型提高代码复用
|
||
interface Repository<T> {
|
||
findAll(): Promise<T[]>;
|
||
findById(id: string): Promise<T>;
|
||
create(entity: T): Promise<T>;
|
||
}
|
||
|
||
// ❌ 避免使用 any(除非确实必要)
|
||
// ✅ 使用 unknown 替代
|
||
function process(data: unknown) {
|
||
// 明确类型或接口
|
||
}
|
||
|
||
// ✅ 使用联合类型明确可能的状态
|
||
type Status = 'pending' | 'success' | 'error';
|
||
```
|
||
|
||
#### 5.1.3 错误处理
|
||
|
||
```typescript
|
||
// ✅ 统一的错误处理模式
|
||
|
||
// 1. 定义错误类型
|
||
class ValidationError extends Error {
|
||
constructor(message: string) {
|
||
super(message);
|
||
this.name = 'ValidationError';
|
||
}
|
||
}
|
||
|
||
class NetworkError extends Error {
|
||
constructor(message: string, code: number) {
|
||
super(message);
|
||
this.name = 'NetworkError';
|
||
this.code = code;
|
||
}
|
||
}
|
||
|
||
// 2. 使用 try-catch 包裹可能失败的代码
|
||
try {
|
||
await apiCall();
|
||
} catch (error) {
|
||
if (error instanceof NetworkError) {
|
||
// 网络错误处理
|
||
} else if (error instanceof ValidationError) {
|
||
// 验证错误处理
|
||
} else {
|
||
// 未知错误处理
|
||
}
|
||
}
|
||
|
||
// 3. 错误日志记录
|
||
console.error('[ERROR]', error.message, error.stack);
|
||
// 或使用日志服务
|
||
logger.error('API call failed', { error, context: { userId, action } });
|
||
```
|
||
|
||
### 5.2 导入与依赖管理
|
||
|
||
```typescript
|
||
// ✅ 明确导入路径(使用绝对导入)
|
||
import { UserService } from './services/user/UserService';
|
||
import { validateUser } from './utils/validators';
|
||
|
||
// ✅ 使用类型导入
|
||
import type { User, UserProfile } from './types';
|
||
|
||
// ✅ 按功能分组导入
|
||
// UI 组件
|
||
import { Button } from './components/ui/Button';
|
||
import { Form } from './components/ui/Form';
|
||
// 工具函数
|
||
import { formatDate } from './utils/dateUtils';
|
||
|
||
// ❌ 避免相对导入(除非在同一目录内)
|
||
// import { Something } from '../shared/Something';
|
||
|
||
// ✅ 使用 barrel exports(index.ts 导出)
|
||
// services/index.ts
|
||
export { UserService, AuthService, OrderService };
|
||
export type { User, Order, Profile };
|
||
```
|
||
|
||
#### 5.2.1 API 调用规范
|
||
|
||
```typescript
|
||
// ✅ 使用 async/await
|
||
async function fetchData(): Promise<Data> {
|
||
const response = await fetch(url);
|
||
return response.json();
|
||
}
|
||
|
||
// ❌ 避免回调地狱(使用 async/await)
|
||
// fetchData((data, callback) => { callback(data); }); // 不推荐
|
||
|
||
// ✅ 正确的错误传播
|
||
async function processOrder(orderId: string): Promise<void> {
|
||
try {
|
||
await validateOrder(orderId);
|
||
await processPayment(orderId);
|
||
await shipOrder(orderId);
|
||
} catch (error) {
|
||
// 统一错误处理
|
||
throw new ProcessingError('Failed to process order', error);
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 6. Wiki 与 PARA 协作指南
|
||
|
||
### 6.1 知识流转路径
|
||
|
||
```mermaid
|
||
graph LR
|
||
Raw[新来源] --> Ingest[Ingest 操作]
|
||
Ingest --> Wiki[wiki/ 页面]
|
||
Wiki -->|价值高| Ref[References/ 归档]
|
||
Wiki -->|个人洞察| Notes[Notes/ 笔记]
|
||
Wiki -->|参考模板| Templ[Templates/]
|
||
|
||
Raw -->|直接阅读| Clippings[Clippings/]
|
||
Clippings -->|价值验证| Ingest
|
||
```
|
||
|
||
### 6.2 操作决策树
|
||
|
||
| 场景 | 操作层 | 工作流 | 示例 |
|
||
|------|--------|--------|------|
|
||
| **收到新文章** | Wiki 层 | Ingest → 编译到 wiki | 读取论文,创建概念页 |
|
||
| **临时摘录** | PARA 层 | Clippings/ → 存储待整理 | 网页摘录,暂存 |
|
||
| **个人感悟** | PARA 层 | Notes/ → 原子笔记 | 阅读后的思考 |
|
||
| **稳定知识** | Wiki 层 | 维护 wiki 页面 | 概念页长期更新 |
|
||
| **模板需求** | Templates/ | 创建模板 | 新内容类型模板 |
|
||
|
||
### 6.3 Frontmatter 一致性
|
||
|
||
确保跨层级的 frontmatter 一致性:
|
||
|
||
| 层级 | categories | tags | type | source |
|
||
|------|-----------|------|------|--------|
|
||
| **PARA 层** | `[[Category]]` | `{tag}` | 可选 | 不需要 |
|
||
| **Wiki 层** | `[[LLM Wiki]]` | `wiki` | **必填** | **必填** |
|
||
|
||
**示例对比**:
|
||
|
||
```yaml
|
||
# PARA 层 - References/Obsidian.md
|
||
---
|
||
categories:
|
||
- "[[Tools]]"
|
||
tags:
|
||
- tools
|
||
- obsidian
|
||
- knowledge-management
|
||
created: 2026-01-23
|
||
rating: 5
|
||
author: []
|
||
---
|
||
|
||
# Obsidian
|
||
|
||
Obsidian is a markdown-based note-taking app...
|
||
```
|
||
|
||
```yaml
|
||
# Wiki 层 - wiki/Obsidian.md
|
||
---
|
||
categories:
|
||
- "[[LLM Wiki]]"
|
||
tags:
|
||
- wiki
|
||
- tool
|
||
- obsidian
|
||
created: 2026-04-07
|
||
source: "[[raw/obsidian-guide.md]]"
|
||
type: tool
|
||
aliases:
|
||
- Obsidian 笔记工具
|
||
---
|
||
|
||
# Obsidian
|
||
|
||
> **一句话描述**:基于 Markdown 的知识管理工具
|
||
|
||
## 基本信息
|
||
|
||
| 属性 | 值 |
|
||
|------|-----|
|
||
| 官网 | https://obsidian.md |
|
||
| 类型 | 知识管理工具 |
|
||
|
||
## 在 LLM Wiki 中的角色
|
||
|
||
Obsidian 是 Wiki 的可视化 IDE,提供 Graph View 查看连接形状。
|
||
|
||
## 来源
|
||
|
||
- [[raw/obsidian-guide.md]] - 官方文档
|
||
```
|
||
|
||
---
|
||
|
||
## 7. 常见任务清单
|
||
|
||
### 7.1 摄入新来源
|
||
|
||
- [ ] 存放来源到 `raw/{source-name}.md`
|
||
- [ ] 读取并分析关键要点
|
||
- [ ] 创建/更新 Wiki 页面(概念/实体/工具)
|
||
- [ ] 更新 `wiki/index.md`(来源数、页面数)
|
||
- [ ] 追加 `wiki/log.md` 条目
|
||
- [ ] 检查是否需要创建 PARA 层引用
|
||
|
||
### 7.2 回答 Wiki 查询
|
||
|
||
- [ ] 搜索相关 Wiki 页面(grep/qmd)
|
||
- [ ] 综合多页面信息
|
||
- [ ] 检查是否有新见解
|
||
- [ ] 如有新见解,创建新 Wiki 页面
|
||
- [ ] 更新 index 和 log
|
||
|
||
### 7.3 Wiki 健康检查
|
||
|
||
- [ ] 检查矛盾声明
|
||
- [ ] 检查过时信息
|
||
- [ ] 检查孤立页面
|
||
- [ ] 检查缺失交叉引用
|
||
- [ ] 更新 log 记录检查结果
|
||
|
||
### 7.4 创建 Marp 演示文稿
|
||
|
||
- [ ] 添加 frontmatter:`marp: "true"`, `theme`, `paginate`
|
||
- [ ] 编写幻灯片内容(每页用 `---` 分隔)
|
||
- [ ] 添加页面类型注释(`<!-- _class: cover -->` 等)
|
||
- [ ] 使用 Obsidian Marp 插件预览
|
||
- [ ] 导出为 HTML/PDF/PPTX
|
||
|
||
### 7.5 自定义 Marp 主题
|
||
|
||
- [ ] 在 `Templates/MarpTheme/` 创建 CSS 文件
|
||
- [ ] 定义 CSS 变量(颜色、字体)
|
||
- [ ] 编写自定义样式规则
|
||
- [ ] 重启 Obsidian 使主题生效
|
||
- [ ] 在 frontmatter 中引用:`theme: theme-name`
|
||
- [ ] 创建示例演示文稿验证主题
|
||
|
||
---
|
||
|
||
## 8. 工具与资源
|
||
|
||
### 8.1 核心工具
|
||
|
||
| 工具 | 用途 | 文档 |
|
||
|------|------|------|
|
||
| **Obsidian** | Wiki 的可视化 IDE | 官方文档 |
|
||
| **qmd** | 本地 Markdown 搜索引擎 | GitHub |
|
||
| **Marp** | 演示文稿工具 | marp.guide |
|
||
| **Obsidian Marp** | Obsidian 中的 Marp 插件 | GitHub |
|
||
|
||
### 8.2 相关 Wiki 页面
|
||
|
||
**LLM Wiki 核心**:
|
||
- [[LLM Wiki]] - 核心模式定义
|
||
- [[RAG vs 持久化知识库]] - 模式对比
|
||
- [[知识库维护自动化]] - 维护负担解决方案
|
||
- [[Memex]] - 思想源头
|
||
|
||
**实践案例**:
|
||
- [[Farzapedia]] - Farza 的实践案例
|
||
- [[BYOAI]] - 四大优势
|
||
- [[Contamination Mitigation]] - Agent 工作区隔离
|
||
|
||
**人物**:
|
||
- [[Andrej Karpathy]] - 模式提出者
|
||
- [[Vannevar Bush]] - Memex 概念提出者
|
||
|
||
**Marp 生态**:
|
||
- [[Marp]] - 概念总览
|
||
- [[Marp 指令语法]] - 指令参考
|
||
- [[Marp 主题与样式]] - 主题和 CSS
|
||
- [[Marp 导出]] - 导出方式
|
||
- [[Obsidian Marp 插件]] - Obsidian 集成
|
||
- [[Marp 主题推荐]] - 社区主题合集
|
||
- [[示例-学校定制Marp演示]] - 演示示例
|
||
|
||
### 8.3 外部资源
|
||
|
||
- [[llm-wiki]] - Karpathy Gist 原文
|
||
- [[刚刚,Karpathy 开源个人 LLM Wiki]] - J0hn 中文解读
|
||
- [[marp-guide]] - Marp 官方文档
|
||
- [[marp-themes]] - GitHub 主题合集
|
||
|
||
---
|
||
|
||
## 9. 附录
|
||
|
||
### 9.1 本文档特殊说明
|
||
|
||
AGENTS.md 是仓库的 **Schema 文件**,位于基础设施层:
|
||
|
||
| 属性 | 值 | 说明 |
|
||
|------|-----|------|
|
||
| **位置** | 仓库根目录 | 与 PARA、wiki、raw 同级 |
|
||
| **角色** | Wiki 结构约定、工作流规范 | 连接 PARA 层和 Wiki 层 |
|
||
| **维护者** | 人类 + LLM | 共同演进 |
|
||
|
||
**Frontmatter 特殊性**:
|
||
- 继承 PARA 层的字段(categories, rating)
|
||
- 添加 Wiki 层的字段(type: schema)
|
||
- 不需要 source 字段(因为是规范本身,非编译产物)
|
||
|
||
### 9.2 文件命名约定
|
||
|
||
| 层级 | 类型 | 命名约定 | 示例 |
|
||
|------|------|----------|------|
|
||
| **raw/** | 来源 | `{source-name}.md` | `llm-wiki.md` |
|
||
| **wiki/** | 概念 | `{概念名称}.md` | `Memex.md` |
|
||
| **wiki/** | 实体 | `{人物姓名}.md` | `Andrej Karpathy.md` |
|
||
| **wiki/** | 工具 | `{工具名称}.md` | `qmd.md` |
|
||
| **wiki/** | 参考 | `{主题}-{子主题}.md` | `Marp-指令语法.md` |
|
||
| **Categories/** | 类别 | `{类别名}s.md` | `Books.md` |
|
||
| **References/** | 实体 | `{实体名称}.md` | `Obsidian.md` |
|
||
| **Notes/** | 笔记 | `{标题}.md` | `Evergreen notes…md` |
|
||
| **Daily/** | 日记 | `{YYYY-MM-DD}.md` | `2026-01-23.md` |
|
||
|
||
### 9.2 Git 忽略规则
|
||
|
||
```
|
||
# Obsidian
|
||
.obsidian/workspace.json
|
||
.obsidian/workspace-mobile.json
|
||
|
||
# 导出文件
|
||
*.pdf
|
||
*.html
|
||
*.pptx
|
||
# 除非是源文件
|
||
|
||
# 临时文件
|
||
.DS_Store
|
||
Thumbs.db
|
||
```
|
||
|
||
### 9.3 更新日志
|
||
|
||
| 日期 | 版本 | 更新内容 |
|
||
|------|------|----------|
|
||
| 2026-01-23 | 1.0 | 初始版本(PARA 模式) |
|
||
| 2026-04-07 | 2.0 | 添加 LLM Wiki 模式、Marp 工作流、双层架构 |
|
||
|
||
---
|
||
|
||
## 名言
|
||
|
||
> "Obsidian is the IDE; LLM is the programmer; wiki is the codebase."
|
||
> — [[Andrej Karpathy]]
|
||
|
||
> "这种个性化方式把控制权完全交到你手上。数据是你的,格式是通用的,内容是可检查的。用哪个 AI 随你,让 AI 公司们卷起来吧。"
|
||
> — [[Andrej Karpathy]]
|