mirror of
https://github.com/tradecatlabs/vibe-coding-cn.git
synced 2026-08-02 13:47:45 +00:00
docs: add anchor gate and folded references toc
This commit is contained in:
@@ -24,7 +24,7 @@ jobs:
|
||||
run: npm install -g markdownlint-cli
|
||||
- name: Run markdownlint
|
||||
run: markdownlint --config .github/lint_config.json --ignore .history --ignore tools/external '**/*.md'
|
||||
- name: Check local markdown links
|
||||
- name: Check local markdown links and anchors
|
||||
run: python3 scripts/check-local-links.py
|
||||
|
||||
link-checker:
|
||||
|
||||
@@ -8,7 +8,7 @@ help:
|
||||
@echo "Available commands:"
|
||||
@echo " help - Show this help message"
|
||||
@echo " lint - Lint all markdown files"
|
||||
@echo " check-links - Check local markdown links"
|
||||
@echo " check-links - Check local markdown links and anchors"
|
||||
@echo " build - Verify knowledge base has no build step"
|
||||
@echo " test - Run repository quality gates"
|
||||
@echo " clean - Remove ignored generated caches"
|
||||
@@ -20,7 +20,7 @@ lint:
|
||||
@markdownlint --config .github/lint_config.json --ignore .history --ignore tools/external '**/*.md'
|
||||
|
||||
check-links:
|
||||
@echo "Checking local markdown links..."
|
||||
@echo "Checking local markdown links and anchors..."
|
||||
@python3 scripts/check-local-links.py
|
||||
|
||||
build:
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
<a href="docs/concepts/README.md#concept-problem-solving"><img src="https://img.shields.io/badge/🧩_问题求解-必读-purple?style=for-the-badge" alt="问题求解"></a>
|
||||
<a href="docs/philosophy/README.md#philosophy-thinking-models"><img src="https://img.shields.io/badge/🧭_思维模型-认知工具-purple?style=for-the-badge" alt="思维模型"></a>
|
||||
<a href="docs/philosophy/README.md#philosophy-methodology-toolbox"><img src="https://img.shields.io/badge/🔮_哲学方法论-底层协议-purple?style=for-the-badge" alt="哲学与方法论"></a>
|
||||
<a href="docs/references/README.md#reference-engineering-practice-4-ai-编程质量门禁与常见坑"><img src="https://img.shields.io/badge/🛡️_工程实践-质量门禁-darkred?style=for-the-badge" alt="工程实践"></a>
|
||||
<a href="docs/references/README.md#quality-gates"><img src="https://img.shields.io/badge/🛡️_工程实践-质量门禁-darkred?style=for-the-badge" alt="工程实践"></a>
|
||||
<a href="docs/concepts/README.md#concept-language-layers"><img src="https://img.shields.io/badge/📊_语言层要素-12层框架-gold?style=for-the-badge" alt="语言层要素"></a>
|
||||
<a href="./skills/"><img src="https://img.shields.io/badge/⚡_Skills-技能大全-forestgreen?style=for-the-badge" alt="skills技能大全"></a>
|
||||
<a href="https://docs.google.com/spreadsheets/d/1Ifk_dLF25ULSxcfGem1hXzJsi7_RBUNAki8SBCuvkJA/edit?gid=1254297203#gid=1254297203"><img src="https://img.shields.io/badge/📋_提示词-在线表格-blue?style=for-the-badge" alt="提示词在线表格"></a>
|
||||
@@ -178,7 +178,7 @@
|
||||
1. [Vibe Coding 经验](docs/getting-started/README.md#1-vibe-coding-经验) - 通用语言能力、人机分工、机器门禁和入门铁律
|
||||
2. [问题求解](docs/concepts/README.md#concept-problem-solving) - “目标-现状-差距-标准”与“目标-约束-对象-路径”的极简框架
|
||||
3. [拼好码](docs/concepts/README.md#concept-glue-coding) - 优先复用成熟能力,用胶水代码连接、编排、适配业务流程
|
||||
4. [工程实践](docs/references/README.md#reference-engineering-practice-4-ai-编程质量门禁与常见坑) - 用项目架构、代码组织、开发经验和硬门禁约束 AI 输出
|
||||
4. [工程实践](docs/references/README.md#quality-gates) - 用项目架构、代码组织、开发经验和硬门禁约束 AI 输出
|
||||
|
||||
</details>
|
||||
|
||||
@@ -407,8 +407,8 @@ pip install -r tools/prompts-library/scripts/requirements.txt
|
||||
* [**Chat Vault**](./tools/chat-vault/): AI 聊天记录保存工具,支持 Codex/Kiro/Gemini/Claude CLI。
|
||||
* [**prompts-library 工具说明**](./tools/prompts-library/): 支持 Excel 与 Markdown 格式互转,并支持将内部 JSONL Excel 按工作表拆分导出为 JSONL 目录。
|
||||
* [**编程提示词集合**](https://docs.google.com/spreadsheets/d/1Ifk_dLF25ULSxcfGem1hXzJsi7_RBUNAki8SBCuvkJA/edit?gid=1254297203#gid=1254297203): 适用于 Vibe Coding 流程的专用提示词(云端表格)。
|
||||
* [**工程实践**](docs/references/README.md#reference-engineering-practice-4-ai-编程质量门禁与常见坑): 项目架构、代码组织、开发经验、AI 编程质量门禁与常见坑的统一入口。
|
||||
* [**技术栈**](docs/references/README.md#reference-technology-stack-十四如何选择技术栈): 常见软件系统技术栈、选型维度、组合案例与初学者学习路径。
|
||||
* [**工程实践**](docs/references/README.md#quality-gates): 项目架构、代码组织、开发经验、AI 编程质量门禁与常见坑的统一入口。
|
||||
* [**技术栈**](docs/references/README.md#tech-stack-selection): 常见软件系统技术栈、选型维度、组合案例与初学者学习路径。
|
||||
* [**系统提示词集合**](https://docs.google.com/spreadsheets/d/1Ifk_dLF25ULSxcfGem1hXzJsi7_RBUNAki8SBCuvkJA/edit?gid=1254297203#gid=1254297203): AI 开发的系统提示词,含多版本开发规范(云端表格)。
|
||||
* [**外部资源(在线表格)**](./assets/README.md): 外部资源的唯一真相源(按类型分表),本地 Markdown 保留为历史参考。
|
||||
|
||||
|
||||
+6
-6
@@ -20,14 +20,14 @@
|
||||
2. [Vibe Coding 经验](./getting-started/README.md#1-vibe-coding-经验)
|
||||
3. [问题求解](concepts/README.md#concept-problem-solving)
|
||||
4. [拼好码](concepts/README.md#concept-glue-coding)
|
||||
5. [工程实践](references/README.md#reference-engineering-practice-顶部导航)
|
||||
5. [工程实践](references/README.md#reference-engineering-practice)
|
||||
|
||||
### 开发者路径
|
||||
|
||||
1. [拼好码](concepts/README.md#concept-glue-coding)
|
||||
2. [系统构建方法](concepts/README.md#concept-system-building)
|
||||
3. [技术栈](references/README.md#reference-technology-stack-顶部导航)
|
||||
4. [工程实践](references/README.md#reference-engineering-practice-顶部导航)
|
||||
3. [技术栈](references/README.md#reference-technology-stack)
|
||||
4. [工程实践](references/README.md#reference-engineering-practice)
|
||||
|
||||
### 思维模型路径
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
2. [docs 目录 AGENTS](./AGENTS.md)
|
||||
3. [从零开始完整入门](./getting-started/README.md#1-学习地图)
|
||||
4. [Vibe Coding 经验](./getting-started/README.md#1-vibe-coding-经验)
|
||||
5. [工程实践](references/README.md#reference-engineering-practice-顶部导航)
|
||||
5. [工程实践](references/README.md#reference-engineering-practice)
|
||||
6. [AI 引用语料](../assets/ai-citation/README.md)
|
||||
|
||||
## 全部文档索引
|
||||
@@ -76,8 +76,8 @@
|
||||
|
||||
- [README](./references/README.md) - 参考资料索引。
|
||||
- [AGENTS](./references/AGENTS.md) - 参考资料目录操作规则。
|
||||
- [工程实践](references/README.md#reference-engineering-practice-顶部导航) - 项目架构、代码组织、开发经验、质量门禁与常见坑。
|
||||
- [技术栈](references/README.md#reference-technology-stack-顶部导航) - 技术栈选型、组合案例与初学者学习路径。
|
||||
- [工程实践](references/README.md#reference-engineering-practice) - 项目架构、代码组织、开发经验、质量门禁与常见坑。
|
||||
- [技术栈](references/README.md#reference-technology-stack) - 技术栈选型、组合案例与初学者学习路径。
|
||||
|
||||
### research
|
||||
|
||||
|
||||
@@ -163,7 +163,7 @@ AI 能安装依赖、执行命令、修复报错、提交 Git;你负责确认
|
||||
| 开发者路线 | 已会写代码 | 建立 AI 结对编程工作流 | [Vibe Coding 经验](#1-vibe-coding-经验) |
|
||||
| Prompt 路线 | 想提升提问质量 | 把需求表达成可执行指令 | [提示词库](../../../prompts/README.md) |
|
||||
| Skill 路线 | 想沉淀复用能力 | 把高频任务做成可重复调用的技能 | [Skills 技能大全](../../../skills/README.md) |
|
||||
| 质量门禁路线 | 担心 AI 乱写代码 | 用测试、CI、schema、清单约束 AI 输出 | [工程实践](../references/README.md#reference-engineering-practice-顶部导航) |
|
||||
| 质量门禁路线 | 担心 AI 乱写代码 | 用测试、CI、schema、清单约束 AI 输出 | [工程实践](../references/README.md#reference-engineering-practice) |
|
||||
| GEO/SEO 路线 | 想提升仓库被引用概率 | 建设 AI 可理解、可引用、可验证的内容资产 | [GEO / SEO 检查清单](../../assets/ai-citation/geo-seo-checklist.md) |
|
||||
|
||||
### 路线一:零基础路线
|
||||
@@ -197,7 +197,7 @@ AI 能安装依赖、执行命令、修复报错、提交 Git;你负责确认
|
||||
先建立人机分工和质量意识。
|
||||
2. [拼好码](../concepts/README.md#concept-glue-coding)
|
||||
优先复用成熟能力,把自研代码限制在连接、编排、适配和业务逻辑。
|
||||
3. [工程实践](../references/README.md#reference-engineering-practice-顶部导航)
|
||||
3. [工程实践](../references/README.md#reference-engineering-practice)
|
||||
在任务开始前写清楚目标、边界、禁止项、验收标准和门禁,并用底层程序逻辑检查项约束实现质量。
|
||||
|
||||
完成标准:
|
||||
@@ -212,7 +212,7 @@ AI 能安装依赖、执行命令、修复报错、提交 Git;你负责确认
|
||||
目标:把自然语言需求写成可执行、可检查、可复用的指令。
|
||||
|
||||
1. [提示词库入口](../../../prompts/README.md)
|
||||
2. [工程实践](../references/README.md#reference-engineering-practice-顶部导航)
|
||||
2. [工程实践](../references/README.md#reference-engineering-practice)
|
||||
3. [语言层要素](../concepts/README.md#concept-language-layers)
|
||||
4. [问题求解](../concepts/README.md#concept-problem-solving)
|
||||
|
||||
@@ -244,7 +244,7 @@ AI 能安装依赖、执行命令、修复报错、提交 Git;你负责确认
|
||||
优先阅读:
|
||||
|
||||
1. [AGENTS.md](../../../../AGENTS.md)
|
||||
2. [工程实践](../references/README.md#reference-engineering-practice-顶部导航)
|
||||
2. [工程实践](../references/README.md#reference-engineering-practice)
|
||||
3. [GEO / SEO 检查清单](../../assets/ai-citation/geo-seo-checklist.md)
|
||||
|
||||
团队约束:
|
||||
|
||||
@@ -11,12 +11,44 @@
|
||||
- 它承载稳定、可执行、可检查、可复用的工程参考资料。
|
||||
- 每个原独立文档都已并入本 README,并通过稳定锚点提供细粒度跳转。
|
||||
|
||||
## 常用入口
|
||||
|
||||
| 目标 | 直接跳转 |
|
||||
|:---|:---|
|
||||
| 新项目结构怎么搭 | [项目架构模板](#reference-engineering-practice-1-项目架构模板) |
|
||||
| AI 代码质量怎么卡住 | [AI 编程质量门禁与常见坑](#quality-gates) |
|
||||
| 系统提示词怎么写 | [系统提示词构建原则](#reference-engineering-practice-1-系统提示词构建原则) |
|
||||
| 强前置条件怎么约束 | [强前置条件约束](#reference-engineering-practice-2-强前置条件约束) |
|
||||
| 常见坑怎么排查 | [常见坑汇总](#reference-engineering-practice-3-常见坑汇总) |
|
||||
| 底层程序逻辑怎么审 | [底层程序逻辑设计与工程优化项](#reference-engineering-practice-5-底层程序逻辑设计与工程优化项) |
|
||||
| 技术栈怎么选 | [如何选择技术栈](#tech-stack-selection) |
|
||||
| 初学者先学什么 | [初学者应该学什么技术栈](#reference-technology-stack-十五初学者应该学什么技术栈) |
|
||||
|
||||
## 总目录
|
||||
|
||||
1. [工程实践](#reference-engineering-practice) - 项目架构、代码组织、开发经验、质量门禁与常见坑。
|
||||
2. [技术栈](#reference-technology-stack) - 技术栈选型、组合案例与学习路径。
|
||||
|
||||
## 细粒度目录
|
||||
## 折叠块语法
|
||||
|
||||
长目录统一使用 `details + summary`,常用入口放在折叠块外,完整细粒度目录放在折叠块内。
|
||||
|
||||
```md
|
||||
<details>
|
||||
<summary><strong>完整细粒度目录(默认收起)</strong></summary>
|
||||
|
||||
### 细粒度目录
|
||||
|
||||
- [章节](#stable-anchor)
|
||||
- [子章节](#stable-child-anchor)
|
||||
|
||||
</details>
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary><strong>完整细粒度目录(默认收起)</strong></summary>
|
||||
|
||||
### 细粒度目录
|
||||
|
||||
- [1. 工程实践](#reference-engineering-practice)
|
||||
- [核心摘要](#reference-engineering-practice-核心摘要)
|
||||
@@ -215,6 +247,8 @@
|
||||
- [二十、面试中如何介绍自己的技术栈](#reference-technology-stack-二十面试中如何介绍自己的技术栈)
|
||||
- [二十一、总结](#reference-technology-stack-二十一总结)
|
||||
|
||||
</details>
|
||||
|
||||
## 和其他目录的边界
|
||||
|
||||
- 检查清单、模板、质量门禁和经验类内容优先收敛到本 README 的工程实践部分。
|
||||
@@ -1244,6 +1278,7 @@ Redis 的作用:
|
||||
* 异步任务处理
|
||||
* 提高系统稳定性与吞吐
|
||||
|
||||
<a id="quality-gates"></a>
|
||||
<a id="reference-engineering-practice-4-ai-编程质量门禁与常见坑"></a>
|
||||
### 4. AI 编程质量门禁与常见坑
|
||||
|
||||
@@ -4897,6 +4932,7 @@ Web 游戏:
|
||||
|
||||
---
|
||||
|
||||
<a id="tech-stack-selection"></a>
|
||||
<a id="reference-technology-stack-十四如何选择技术栈"></a>
|
||||
### 十四、如何选择技术栈
|
||||
|
||||
|
||||
+1
-1
@@ -4,4 +4,4 @@
|
||||
|
||||
当前已有:
|
||||
|
||||
- `check-local-links.py`:仓库内 Markdown 相对链接检查脚本。
|
||||
- `check-local-links.py`:仓库内 Markdown 相对链接与锚点检查脚本。
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Check local Markdown links that should resolve inside this repository."""
|
||||
"""Check local Markdown links and anchors that should resolve in this repository."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -21,7 +21,6 @@ LINK_PATTERNS = [
|
||||
re.compile(r"\b(?:href|src)=[\"']([^\"']+)[\"']"),
|
||||
]
|
||||
EXTERNAL_PREFIXES = (
|
||||
"#",
|
||||
"http://",
|
||||
"https://",
|
||||
"wss://",
|
||||
@@ -32,6 +31,72 @@ EXTERNAL_PREFIXES = (
|
||||
)
|
||||
|
||||
|
||||
def github_slug(title: str) -> str:
|
||||
"""Approximate GitHub Markdown heading anchors for local validation."""
|
||||
title = re.sub(r"<[^>]+>", "", title.strip().lower())
|
||||
title = re.sub(r"[`*_~]", "", title)
|
||||
title = re.sub(r"[^\w\u4e00-\u9fff\- ]+", "", title)
|
||||
title = re.sub(r"\s+", "-", title).strip("-")
|
||||
return title
|
||||
|
||||
|
||||
def strip_fenced_code(text: str) -> str:
|
||||
"""Remove fenced code blocks before scanning inline links."""
|
||||
lines: list[str] = []
|
||||
in_fence = False
|
||||
fence_marker = ""
|
||||
|
||||
for line in text.splitlines():
|
||||
stripped = line.lstrip()
|
||||
if stripped.startswith(("```", "~~~")):
|
||||
marker = stripped[:3]
|
||||
if not in_fence:
|
||||
in_fence = True
|
||||
fence_marker = marker
|
||||
elif marker == fence_marker:
|
||||
in_fence = False
|
||||
fence_marker = ""
|
||||
lines.append("")
|
||||
continue
|
||||
lines.append("" if in_fence else line)
|
||||
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
def markdown_anchors(path: Path) -> set[str]:
|
||||
text = path.read_text(encoding="utf-8", errors="ignore")
|
||||
anchors = set(re.findall(r"<a\s+id=[\"']([^\"']+)[\"']", text))
|
||||
used: dict[str, int] = {}
|
||||
in_fence = False
|
||||
fence_marker = ""
|
||||
|
||||
for line in text.splitlines():
|
||||
stripped = line.lstrip()
|
||||
if stripped.startswith(("```", "~~~")):
|
||||
marker = stripped[:3]
|
||||
if not in_fence:
|
||||
in_fence = True
|
||||
fence_marker = marker
|
||||
elif marker == fence_marker:
|
||||
in_fence = False
|
||||
fence_marker = ""
|
||||
continue
|
||||
if in_fence:
|
||||
continue
|
||||
|
||||
heading = re.match(r"^(#{1,6})\s+(.+?)\s*#*\s*$", line)
|
||||
if not heading:
|
||||
continue
|
||||
slug = github_slug(heading.group(2))
|
||||
if not slug:
|
||||
continue
|
||||
count = used.get(slug, 0)
|
||||
used[slug] = count + 1
|
||||
anchors.add(slug if count == 0 else f"{slug}-{count}")
|
||||
|
||||
return anchors
|
||||
|
||||
|
||||
def should_skip(path: Path) -> bool:
|
||||
rel = path.relative_to(ROOT)
|
||||
if any(part in SKIP_PARTS for part in rel.parts):
|
||||
@@ -39,17 +104,23 @@ def should_skip(path: Path) -> bool:
|
||||
return any(rel == prefix or prefix in rel.parents for prefix in SKIP_PREFIXES)
|
||||
|
||||
|
||||
def normalize_target(raw: str) -> str:
|
||||
def normalize_target(raw: str) -> tuple[str, str]:
|
||||
raw = raw.strip()
|
||||
if not raw or raw.startswith(EXTERNAL_PREFIXES):
|
||||
return ""
|
||||
return "", ""
|
||||
target = raw.split()[0] if " " in raw and not raw.startswith("<") else raw
|
||||
target = target.strip("<>").split("#", 1)[0]
|
||||
return urllib.parse.unquote(target)
|
||||
target = target.strip("<>")
|
||||
if "#" in target:
|
||||
path_part, anchor = target.split("#", 1)
|
||||
else:
|
||||
path_part, anchor = target, ""
|
||||
return urllib.parse.unquote(path_part), urllib.parse.unquote(anchor)
|
||||
|
||||
|
||||
def main() -> int:
|
||||
missing: list[tuple[Path, str, Path]] = []
|
||||
missing_links: list[tuple[Path, str, Path]] = []
|
||||
missing_anchors: list[tuple[Path, str, Path, str]] = []
|
||||
anchor_cache: dict[Path, set[str]] = {}
|
||||
checked_files = 0
|
||||
|
||||
for markdown_file in sorted(ROOT.rglob("*.md")):
|
||||
@@ -57,31 +128,42 @@ def main() -> int:
|
||||
continue
|
||||
checked_files += 1
|
||||
text = markdown_file.read_text(encoding="utf-8", errors="ignore")
|
||||
scan_text = strip_fenced_code(text)
|
||||
|
||||
for pattern in LINK_PATTERNS:
|
||||
for match in pattern.finditer(text):
|
||||
for match in pattern.finditer(scan_text):
|
||||
raw = match.group(1)
|
||||
target = normalize_target(raw)
|
||||
if not target or target.startswith(("/", "\\")):
|
||||
target, anchor = normalize_target(raw)
|
||||
if target.startswith(("/", "\\")):
|
||||
continue
|
||||
|
||||
destination = (markdown_file.parent / target).resolve()
|
||||
destination = (markdown_file.parent / target).resolve() if target else markdown_file.resolve()
|
||||
try:
|
||||
destination.relative_to(ROOT)
|
||||
except ValueError:
|
||||
continue
|
||||
|
||||
if not destination.exists():
|
||||
missing.append((markdown_file.relative_to(ROOT), raw, markdown_file.parent / target))
|
||||
missing_links.append((markdown_file.relative_to(ROOT), raw, markdown_file.parent / target))
|
||||
continue
|
||||
if anchor and destination.suffix.lower() == ".md":
|
||||
if destination not in anchor_cache:
|
||||
anchor_cache[destination] = markdown_anchors(destination)
|
||||
if anchor not in anchor_cache[destination]:
|
||||
missing_anchors.append((markdown_file.relative_to(ROOT), raw, destination.relative_to(ROOT), anchor))
|
||||
|
||||
if missing:
|
||||
if missing_links or missing_anchors:
|
||||
print("MISSING_LINKS")
|
||||
for source, raw, resolved in missing:
|
||||
for source, raw, resolved in missing_links:
|
||||
print(f"{source} -> {raw} => {resolved.relative_to(ROOT)}")
|
||||
print(f"TOTAL={len(missing)}")
|
||||
print("MISSING_ANCHORS")
|
||||
for source, raw, destination, anchor in missing_anchors:
|
||||
print(f"{source} -> {raw} => {destination}#{anchor}")
|
||||
print(f"TOTAL_LINKS={len(missing_links)}")
|
||||
print(f"TOTAL_ANCHORS={len(missing_anchors)}")
|
||||
return 1
|
||||
|
||||
print(f"OK local links checked: {checked_files} files")
|
||||
print(f"OK local links and anchors checked: {checked_files} files")
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
@@ -30,10 +30,10 @@
|
||||
<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>
|
||||
|
||||
[✨ 功能特性](#-功能特性) •
|
||||
[🚀 快速开始](#-快速开始) •
|
||||
[✨ 功能特性](#功能特性) •
|
||||
[🚀 快速开始](#快速开始) •
|
||||
[⚙️ 架构与工作流程](#architecture-workflow) •
|
||||
[🤝 参与贡献](#-参与贡献) •
|
||||
[🤝 参与贡献](#参与贡献) •
|
||||
[🗺️ 路线图](#roadmap)
|
||||
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user