From 3020e5efe5990285f1fd8964117e35eaac70c0e0 Mon Sep 17 00:00:00 2001 From: tradecatlabs <288998340+tradecatlabs@users.noreply.github.com> Date: Sun, 25 Oct 2026 07:56:37 +0800 Subject: [PATCH] docs: getting-started - rename guide filenames (#246) --- .github/ai-citation-README.md | 2 +- .github/book_views.py | 14 +- .github/faq.md | 2 +- .github/getting-started-AGENTS.md | 8 +- .github/getting-started-README.md | 20 +- ...rst-project.md => how-to-complete-work.md} | 2 +- .github/llms-full.txt | 4 +- .github/{god.md => pi-cli-setup.md} | 0 .github/redirects.yml | 27 ++- .github/summary-long.md | 2 +- .github/taxonomy.yml | 10 +- .github/test-source-archive.py | 190 +++++++++--------- README.md | 6 +- llms.txt | 4 +- 14 files changed, 155 insertions(+), 136 deletions(-) rename .github/{first-project.md => how-to-complete-work.md} (98%) rename .github/{god.md => pi-cli-setup.md} (100%) diff --git a/.github/ai-citation-README.md b/.github/ai-citation-README.md index 466e6301..5914a3ec 100644 --- a/.github/ai-citation-README.md +++ b/.github/ai-citation-README.md @@ -21,7 +21,7 @@ AI引用语料平铺在`.github/`根;原名不冲突的内容文件保持原 | `.github/context/gongfa/README.md#doc-ai-core-propositions` | 功法体系内的六条核心命题正文;固定目标、可变策略与分层反馈是协作模型,不保证自动收敛或已验证效果 | | `.github/context/README.md` | 知识库总索引 | | `.github/getting-started-README.md` | 从零开始完整入门 | -| `.github/first-project.md` | 《如何完成工作》可选指南:围绕自选目标按需选择方法并以证据验收,不预设具体任务或固定流程 | +| `.github/how-to-complete-work.md` | 《如何完成工作》可选指南:围绕自选目标按需选择方法并以证据验收,不预设具体任务或固定流程 | | `.github/context/gongfa/README.md` | 轻量分阶导航与原文索引;对象说明见天、地、玄、黄四阶页,冻结原文保存在`data.json` | | `.github/context/gongfa/README.md#doc-vibe-coding-cultivation-model` | BFO 下层展开的修仙通俗解释与任务战力评价 | | `.github/context/faqi/README.md#doc-faqi-system` | Vibe Coding工具与依赖分类、重要性分级和正式效能边界 | diff --git a/.github/book_views.py b/.github/book_views.py index d606b35d..85cf810d 100644 --- a/.github/book_views.py +++ b/.github/book_views.py @@ -35,9 +35,13 @@ def relocated(path, fragment=''): if name == '__init__.py': return '.github/source_boundaries.py', fragment aliases = { - '.github/learning-map.md': '.github/god.md', - '.github/context/getting-started/learning-map.md': '.github/god.md', - '.github/docs/getting-started/learning-map.md': '.github/god.md', + '.github/learning-map.md': '.github/pi-cli-setup.md', + '.github/context/getting-started/learning-map.md': '.github/pi-cli-setup.md', + '.github/docs/getting-started/learning-map.md': '.github/pi-cli-setup.md', + '.github/god.md': '.github/pi-cli-setup.md', + '.github/first-project.md': '.github/how-to-complete-work.md', + '.github/context/getting-started/first-project.md': '.github/how-to-complete-work.md', + '.github/docs/getting-started/first-project.md': '.github/how-to-complete-work.md', '.github/context/tool-explanation-template-v0.md': '.github/tool-explanation-template-v0.md', '.github/context/tool-explanation-template-v1.md': '.github/tool-explanation-template-v1.md', '.github/metadata/faqi/README.md': '.github/context/faqi/README.md', @@ -48,7 +52,7 @@ def relocated(path, fragment=''): } if path in aliases: target = aliases[path] - return target, '' if target == '.github/god.md' else fragment + return target, '' if target == '.github/pi-cli-setup.md' else fragment flat_groups = { '.github/context/ai-citation': 'ai-citation', '.github/context/metadata': 'metadata', @@ -158,7 +162,7 @@ def relocated(path, fragment=''): route = root_route if path == prefix else 'blob' return ('https://github.com/tradecatlabs/vibe-coding-cn/' + route + '/' + revision + '/' + quote(path, safe='/')), fragment - return path, '' if path == '.github/god.md' else fragment + return path, '' if path == '.github/pi-cli-setup.md' else fragment def reference(value, original_path, output_path): diff --git a/.github/faq.md b/.github/faq.md index 6a12bb72..c88c594c 100644 --- a/.github/faq.md +++ b/.github/faq.md @@ -23,7 +23,7 @@ 新手优先看: 1. `.github/getting-started-README.md` -2. `.github/first-project.md` +2. `.github/how-to-complete-work.md` 3. `.github/context/gongfa/README.md#doc-problem-solving` 4. `.github/context/gongfa/README.md#doc-glue-coding` 5. `.github/context/gongfa/README.md#doc-project-architecture-template` diff --git a/.github/getting-started-AGENTS.md b/.github/getting-started-AGENTS.md index f2ebe50e..be815ea6 100644 --- a/.github/getting-started-AGENTS.md +++ b/.github/getting-started-AGENTS.md @@ -9,15 +9,15 @@ | 文件 | 职责 | |---|---| | `getting-started-README.md` | 入门索引 | -| `god.md` | Pi CLI 安装与配置指南:用户全文复制给网页版 Chat AI,按步引导并核验 Pi CLI、OpenAI GPT 与本机 Bash | -| `first-project.md` | 《如何完成工作》:围绕自选目标按需选择方法、实施或观察并以证据验收;不预设具体任务或固定流程 | +| `pi-cli-setup.md` | Pi CLI 安装与配置指南:用户全文复制给网页版 Chat AI,按步引导并核验 Pi CLI、OpenAI GPT 与本机 Bash | +| `how-to-complete-work.md` | 《如何完成工作》:围绕自选目标按需选择方法、实施或观察并以证据验收;不预设具体任务或固定流程 | | `getting-started-AGENTS.md` | 本组维护规则 | ## 修改规则 - 根`README.md`是唯一主页;`getting-started-README.md`只做导航,不复制完整教程。 -- `god.md` 本身就是给网页版 Chat AI 的完整提示词:文件头要求用户全文复制并逐轮互动;网页 AI 首轮简短说明路线;系统不明时才问系统,已提供的系统/终端信息直接复用;实际终端未确认或未就绪时指导打开/确认本机终端(Android 使用 Termux;仅在 Termux 未安装时才说明其官方来源与安装影响并等待用户明确决定),若用户尚无检查结果且系统、实际终端已明确且已打开,可直接安排 M0 只读版本检查;已回报目标终端的版本号则复用证据并跳过,已回报错误则按对应错误分支处理、不重复初始检查(仅允许明确规定的条件性重试);Android/Termux 按 Pi 官方 Termux 指南引导,不套用桌面安装命令。再从 M0 引导到 M4,按需检查/安装 Pi CLI、准备网络、连接 OpenAI GPT、验证本机 Bash;若 CLI 已验证可用则跳过安装专用网络检查与安装步骤。安装阶段只核对当前安装路线所需目标,不逐项探测未触发的安装源;短网络探测须设置连接和总时限,并说明超时不等于不可达;OpenAI 模型网络检查仅在 M4.1 按所选登录路线与实际故障执行;Pi 的 OpenAI GPT 路线区分 ChatGPT 订阅 OAuth(provider `openai-codex`)和 OpenAI API Key,不得将 ChatGPT 订阅等同 API 额度;用户另选本地模型时按请求可另行指导,但不计作 OpenAI GPT 验证或满足完成标准第 2 项;仅 API Key 路线可探测 `api.openai.com`,订阅 OAuth 不用该端点代测。安装路线默认优先对应系统的官方安装器,且每轮只展示一条当前路线。完成标准第 2 项只计 Pi 会话中所选 OpenAI GPT 模型对简单问题的实际回答,网页版 Chat AI 自身回复不算;必须等全部完成标准有真实证据后才报告完成,不得停在版本号、模型回答或单次命令检查。网页 AI 只核对用户回报,不能冒充本机执行。本文完成范围限 Pi CLI、OpenAI GPT 与本机 Bash 通路,不承诺所有扩展、项目任务或自动化,不另维护重复提示词或项目开发步骤。 -- `god.md` 使用正常 Markdown 排版,标题、段落和链接直接渲染;粗体标记 `**...**` 与紧邻的中文正文之间保留空格,并通过提示词契约测试确认真实渲染;仅命令和对话示例保留独立代码块,不用外层围栏包住全文。整篇使用 GitHub 文件页右上角的原生全文复制按钮。移除折叠标签、HTML 锚点和页内章节链接;入站链接及历史重定向直接指向 `god.md`,文集链接不生成失效片段。修改时移除宗教话语,改用简洁、中性的技术描述,并保留操作流程、安全边界和完成标准;不使用宗教标题、经文引用或宗教隐喻,也不因此改变授权或效果边界。 +- `pi-cli-setup.md` 本身就是给网页版 Chat AI 的完整提示词:文件头要求用户全文复制并逐轮互动;网页 AI 首轮简短说明路线;系统不明时才问系统,已提供的系统/终端信息直接复用;实际终端未确认或未就绪时指导打开/确认本机终端(Android 使用 Termux;仅在 Termux 未安装时才说明其官方来源与安装影响并等待用户明确决定),若用户尚无检查结果且系统、实际终端已明确且已打开,可直接安排 M0 只读版本检查;已回报目标终端的版本号则复用证据并跳过,已回报错误则按对应错误分支处理、不重复初始检查(仅允许明确规定的条件性重试);Android/Termux 按 Pi 官方 Termux 指南引导,不套用桌面安装命令。再从 M0 引导到 M4,按需检查/安装 Pi CLI、准备网络、连接 OpenAI GPT、验证本机 Bash;若 CLI 已验证可用则跳过安装专用网络检查与安装步骤。安装阶段只核对当前安装路线所需目标,不逐项探测未触发的安装源;短网络探测须设置连接和总时限,并说明超时不等于不可达;OpenAI 模型网络检查仅在 M4.1 按所选登录路线与实际故障执行;Pi 的 OpenAI GPT 路线区分 ChatGPT 订阅 OAuth(provider `openai-codex`)和 OpenAI API Key,不得将 ChatGPT 订阅等同 API 额度;用户另选本地模型时按请求可另行指导,但不计作 OpenAI GPT 验证或满足完成标准第 2 项;仅 API Key 路线可探测 `api.openai.com`,订阅 OAuth 不用该端点代测。安装路线默认优先对应系统的官方安装器,且每轮只展示一条当前路线。完成标准第 2 项只计 Pi 会话中所选 OpenAI GPT 模型对简单问题的实际回答,网页版 Chat AI 自身回复不算;必须等全部完成标准有真实证据后才报告完成,不得停在版本号、模型回答或单次命令检查。网页 AI 只核对用户回报,不能冒充本机执行。本文完成范围限 Pi CLI、OpenAI GPT 与本机 Bash 通路,不承诺所有扩展、项目任务或自动化,不另维护重复提示词或项目开发步骤。 +- `pi-cli-setup.md` 使用正常 Markdown 排版,标题、段落和链接直接渲染;粗体标记 `**...**` 与紧邻的中文正文之间保留空格,并通过提示词契约测试确认真实渲染;仅命令和对话示例保留独立代码块,不用外层围栏包住全文。整篇使用 GitHub 文件页右上角的原生全文复制按钮。移除折叠标签、HTML 锚点和页内章节链接;入站链接及历史重定向直接指向 `pi-cli-setup.md`,文集链接不生成失效片段。修改时移除宗教话语,改用简洁、中性的技术描述,并保留操作流程、安全边界和完成标准;不使用宗教标题、经文引用或宗教隐喻,也不因此改变授权或效果边界。 - 安装方式、Node.js 版本要求、系统支持和 provider 流程以 Pi 当前官方文档与安装入口为准;链接及命令须明确系统、终端、影响和成功判断。官方资料未说明的内容标为未知,不猜测。 - 区分 `pi --version`、模型授权/可用和项目任务完成;不把 CLI 安装说成模型已接通或项目环境已就绪。模型授权前,M4.0 先说明目录资源加载、会话保存与信任提示的影响,再引导用户在目标终端用 `pi` 进入交互界面;`/login`、`/model` 和问题在 Pi 输入框而非系统终端或网页版 AI 输入。已有目标目录的 Pi 会话直接复用,M4.2 不要求重新启动;空目录不是沙箱。M4.1 复用目标环境、路线与模型均未变化且无新失败信号的 GPT 成功回答,不重复登录或提问;已配置但无回答时仍须实际验证,只有缺少授权或实际鉴权失败才处理登录,不能将网络超时、限额或模型不可用直接归因于凭据失效,不为常规验证退出账号、删除或覆盖凭据。 - 不把 WSL、Git、Python、编辑器、代理或项目依赖设为 Pi CLI 安装的通用前置条件。Windows 原生 Git Bash 是内置 Bash 工具的命令环境,不是 CLI 安装本身的要求。 diff --git a/.github/getting-started-README.md b/.github/getting-started-README.md index bf9f5b8c..7315187c 100644 --- a/.github/getting-started-README.md +++ b/.github/getting-started-README.md @@ -2,16 +2,16 @@ ## 字多不看 -- [Pi CLI 安装与配置指南](god.md)需全文复制到网页版 Chat AI 并逐轮互动:先确认操作系统和终端,再检查现有 Pi;只有没有可用 CLI 且用户同意时才按本机路线准备网络、安装并验证。之后再配置 OpenAI GPT 与 Bash;每轮只做一项,不能只凭版本号或模型回答结项。需要代理时按用户选择走 FlClash。 -- `pi --version` 只证明 CLI 可用;模型回答不证明本机工具可用或具体工作已完成,必须另看真实工具调用。项目依赖和具体工作不属于安装验收;[如何完成工作](first-project.md)是独立可选指南。 -- [如何完成工作](first-project.md)是独立可选指南,不是安装条件。 +- [Pi CLI 安装与配置指南](pi-cli-setup.md)需全文复制到网页版 Chat AI 并逐轮互动:先确认操作系统和终端,再检查现有 Pi;只有没有可用 CLI 且用户同意时才按本机路线准备网络、安装并验证。之后再配置 OpenAI GPT 与 Bash;每轮只做一项,不能只凭版本号或模型回答结项。需要代理时按用户选择走 FlClash。 +- `pi --version` 只证明 CLI 可用;模型回答不证明本机工具可用或具体工作已完成,必须另看真实工具调用。项目依赖和具体工作不属于安装验收;[如何完成工作](how-to-complete-work.md)是独立可选指南。 +- [如何完成工作](how-to-complete-work.md)是独立可选指南,不是安装条件。 ## 快速导航 | 文档 | 定位 | |:---|:---| -| [Pi CLI 安装与配置指南](god.md) | 网页 Chat AI 先确认操作系统/终端并检查现有 Pi;必要时按本机路线处理安装网络、安装并验证 CLI,再继续 OpenAI GPT 与本机 Bash。 | -| [如何完成工作](first-project.md) | 可选指南:围绕自选目标选择必要方法、实施或观察并以证据验收;不预设具体任务或固定流程。 | +| [Pi CLI 安装与配置指南](pi-cli-setup.md) | 网页 Chat AI 先确认操作系统/终端并检查现有 Pi;必要时按本机路线处理安装网络、安装并验证 CLI,再继续 OpenAI GPT 与本机 Bash。 | +| [如何完成工作](how-to-complete-work.md) | 可选指南:围绕自选目标选择必要方法、实施或观察并以证据验收;不预设具体任务或固定流程。 | | [Vibe Coding 经验](context/gongfa/README.md#doc-vibe-coding-experience) | 功法文集:理解人机分工、验证和质量边界。 |
@@ -19,18 +19,18 @@ ### 细粒度目录 -- [Pi CLI 安装与配置指南](god.md) - 全文复制给网页版 Chat AI;从操作系统、本机终端(Android 使用 Termux)和现有 Pi 检查开始,按本机路线逐步准备安装网络、安装并验证 CLI,再继续模型和 Bash 验收。 -- [如何完成工作](first-project.md) - 可选指南:围绕自选目标编排必要方法并以证据验收;不预设具体任务或固定流程。 +- [Pi CLI 安装与配置指南](pi-cli-setup.md) - 全文复制给网页版 Chat AI;从操作系统、本机终端(Android 使用 Termux)和现有 Pi 检查开始,按本机路线逐步准备安装网络、安装并验证 CLI,再继续模型和 Bash 验收。 +- [如何完成工作](how-to-complete-work.md) - 可选指南:围绕自选目标编排必要方法并以证据验收;不预设具体任务或固定流程。 - [Vibe Coding 经验](context/gongfa/README.md#doc-vibe-coding-experience) - 功法文集:理解人机分工、验证和质量边界。
## 使用方式 -- 完全新手将[Pi CLI 安装与配置指南](god.md)全文复制到可用的网页版 AI;AI 首轮先问操作系统,不熟悉终端时先指导打开本机终端(Android 使用 Termux),再逐轮互动。已有 Pi 的用户先运行 `pi --version`,成功就复用证据、不重装。 +- 完全新手将[Pi CLI 安装与配置指南](pi-cli-setup.md)全文复制到可用的网页版 AI;AI 首轮先问操作系统,不熟悉终端时先指导打开本机终端(Android 使用 Termux),再逐轮互动。已有 Pi 的用户先运行 `pi --version`,成功就复用证据、不重装。 - 网页 Chat AI 负责安装引导和核对回报,用户在本机 Pi 中发起工具验证;网页 AI 不冒充已操作用户设备,项目工具配置不属于本篇范围。 -- 需要处理一项具体工作时,可按需阅读[如何完成工作](first-project.md),围绕目标选择必要方法并用证据验收;想了解通用协作原则时按需读[Vibe Coding 经验](context/gongfa/README.md#doc-vibe-coding-experience)。 +- 需要处理一项具体工作时,可按需阅读[如何完成工作](how-to-complete-work.md),围绕目标选择必要方法并用证据验收;想了解通用协作原则时按需读[Vibe Coding 经验](context/gongfa/README.md#doc-vibe-coding-experience)。 ## 正文 -本组文件的网络核对、Pi CLI 检查与必要安装、OpenAI GPT 配置和本机 Bash 使用验收统一维护于可全文复制的[Pi CLI 安装与配置指南](god.md)。先按安装阶段检查当前路线所需网络并验证 CLI,再进入模型网络与授权;网页 Chat AI 每轮等待用户回报。只读命令检查不证明其他工具、具体工作或自动化;[如何完成工作](first-project.md)是独立可选指南。 +本组文件的网络核对、Pi CLI 检查与必要安装、OpenAI GPT 配置和本机 Bash 使用验收统一维护于可全文复制的[Pi CLI 安装与配置指南](pi-cli-setup.md)。先按安装阶段检查当前路线所需网络并验证 CLI,再进入模型网络与授权;网页 Chat AI 每轮等待用户回报。只读命令检查不证明其他工具、具体工作或自动化;[如何完成工作](how-to-complete-work.md)是独立可选指南。 diff --git a/.github/first-project.md b/.github/how-to-complete-work.md similarity index 98% rename from .github/first-project.md rename to .github/how-to-complete-work.md index a0e6cdeb..4945524e 100644 --- a/.github/first-project.md +++ b/.github/how-to-complete-work.md @@ -26,7 +26,7 @@ - 只准备当前目标确实需要的工具。安装软件或改系统设置前,先说明目的、影响和恢复方式,等你决定;网络访问仅限必要目标,优先使用官方资料,上传数据、操作外部服务或产生其他外部影响前先说明并得到确认。若使用云端或网页版AI,提示和交给模型处理的文件内容会发送给服务商处理;只提供你有权且愿意分享的最少非敏感内容,无法确认服务是否本地时,按云端处理或暂停。 - Pi 以当前账户权限运行,并不是安全沙箱;不要用管理员或 `root` 启动。执行前审阅命令,完成后检查真实文件差异。 -如果准备使用 Pi CLI,先按[Pi CLI 上手指南](god.md)完成适用的基础配置;已具备可用工具时不必重复安装。CLI 可用、模型能回答和工作目标完成是不同的验收事项。 +如果准备使用 Pi CLI,先按[Pi CLI 上手指南](pi-cli-setup.md)完成适用的基础配置;已具备可用工具时不必重复安装。CLI 可用、模型能回答和工作目标完成是不同的验收事项。 ## 功法编排:从问题决定方法 diff --git a/.github/llms-full.txt b/.github/llms-full.txt index 9236c466..06c32ea3 100644 --- a/.github/llms-full.txt +++ b/.github/llms-full.txt @@ -50,9 +50,9 @@ GEOFlow 的关键启发是:GEO 不是关键词堆砌,而是内容工程链 - .github/context/README.md:知识库总索引,提供新手、开发者、思维模型和 AI Agent 读取路径。 - .github/getting-started-README.md:入门索引,链接可全文复制给网页版 AI 的 Pi CLI 提示词(先确认系统/终端并检查现有 Pi;必要时按安装路线核对网络、安装并验证 CLI,再接通 OpenAI GPT)与独立可选的《如何完成工作》指南;通用Vibe Coding经验正文见 .github/context/gongfa/README.md#doc-vibe-coding-experience。 - .github/context/gongfa/README.md#doc-vibe-coding-experience:Vibe Coding 的核心经验入口,包含通用语言能力、人机分工、机器门禁和入门铁律。 -- .github/god.md:Pi CLI 安装与配置指南,用户全文复制给网页版 Chat AI,按阶段引导检查或安装 Pi CLI、连接 OpenAI GPT,并由用户在本机验证 Bash 工具调用。引导过程逐步等待用户回报,不代替用户操作或授权;CLI 版本、模型回答和 Bash 调用是不同证据,只有三项均有真实结果才报告本文范围内流程完成。OpenAI API 网络检查仅在模型配置阶段且出现真实故障时进行;用户选择 FlClash 路线后,启用 TUN、系统代理和全局模式前先说明流量/隐私影响及恢复方式并等待确认。订阅 URL 属于凭据。本文不承诺所有扩展、具体项目任务或自动化已配置。 +- .github/pi-cli-setup.md:Pi CLI 安装与配置指南,用户全文复制给网页版 Chat AI,按阶段引导检查或安装 Pi CLI、连接 OpenAI GPT,并由用户在本机验证 Bash 工具调用。引导过程逐步等待用户回报,不代替用户操作或授权;CLI 版本、模型回答和 Bash 调用是不同证据,只有三项均有真实结果才报告本文范围内流程完成。OpenAI API 网络检查仅在模型配置阶段且出现真实故障时进行;用户选择 FlClash 路线后,启用 TUN、系统代理和全局模式前先说明流量/隐私影响及恢复方式并等待确认。订阅 URL 属于凭据。本文不承诺所有扩展、具体项目任务或自动化已配置。 - 原 Codex 全局配置基线及安装/恢复脚本已按用户要求移除;历史 Codex 研究资料仅保存在本机副本,不作为 Pi 安装路线。 -- .github/first-project.md:《如何完成工作》可选指南:围绕自选目标按需编排方法、实施或观察并以证据验收;不预设具体任务或固定流程。 +- .github/how-to-complete-work.md:《如何完成工作》可选指南:围绕自选目标按需编排方法、实施或观察并以证据验收;不预设具体任务或固定流程。 - .github/context/gongfa/README.md:按理解、求解、设计、实现、验证、转化和内容身份导航的统一功法文集。 - .github/context/gongfa/README.md#doc-ai-core-propositions:AI 协作的完整核心命题。 - .github/context/gongfa/README.md#doc-dao-fa-shu-qi:人机协作、抽象方法、工程流程与工具承载。 diff --git a/.github/god.md b/.github/pi-cli-setup.md similarity index 100% rename from .github/god.md rename to .github/pi-cli-setup.md diff --git a/.github/redirects.yml b/.github/redirects.yml index 4e390474..6c13de90 100644 --- a/.github/redirects.yml +++ b/.github/redirects.yml @@ -43,11 +43,11 @@ redirects: - from: .github/context/getting-started/README.md to: .github/getting-started-README.md - from: .github/context/getting-started/first-project.md - to: .github/first-project.md + to: .github/how-to-complete-work.md - from: .github/context/getting-started/learning-map.md - to: .github/god.md + to: .github/pi-cli-setup.md - from: .github/learning-map.md - to: .github/god.md + to: .github/pi-cli-setup.md - from: .github/context/tool-explanation-template-v0.md to: .github/tool-explanation-template-v0.md - from: .github/context/tool-explanation-template-v1.md @@ -111,15 +111,15 @@ redirects: - from: docs/getting-started/Codex-CLI配置.md to: .github/context/README.md#本地研究资料 - from: docs/getting-started/学习地图.md - to: .github/god.md + to: .github/pi-cli-setup.md - from: docs/getting-started/Vibe Coding 经验.md to: .github/context/gongfa/README.md#doc-vibe-coding-experience - from: docs/getting-started/网络环境配置.md - to: .github/god.md + to: .github/pi-cli-setup.md - from: docs/getting-started/CLI配置.md - to: .github/god.md + to: .github/pi-cli-setup.md - from: docs/getting-started/开发环境搭建.md - to: .github/god.md + to: .github/pi-cli-setup.md - from: docs/references/通用项目架构模板.md to: .github/context/gongfa/README.md#doc-project-architecture-template - from: docs/references/数据集导向数据服务模板.md @@ -149,7 +149,7 @@ redirects: - from: assets/repos/ to: .github/extensions/ - from: assets/config/ - to: .github/god.md + to: .github/pi-cli-setup.md - from: docs/concepts/问题求解.md to: .github/context/gongfa/README.md#doc-problem-solving - from: docs/concepts/拼好码.md @@ -271,8 +271,13 @@ redirects: # Pi CLI 入门分篇已合并到一份完整指南。 - from: .github/context/getting-started/cli-setup.md - to: .github/god.md + to: .github/pi-cli-setup.md - from: .github/context/getting-started/network-environment.md - to: .github/god.md + to: .github/pi-cli-setup.md - from: .github/context/getting-started/development-environment.md - to: .github/god.md + to: .github/pi-cli-setup.md + # 原平铺入口重命名后只保留历史路径映射,不保留兼容文件。 + - from: .github/god.md + to: .github/pi-cli-setup.md + - from: .github/first-project.md + to: .github/how-to-complete-work.md diff --git a/.github/summary-long.md b/.github/summary-long.md index 0e739de1..4a316020 100644 --- a/.github/summary-long.md +++ b/.github/summary-long.md @@ -6,4 +6,4 @@ 因此,当用户想按任务组织已有Vibe Coding资料、Skill与小工具,理解来源与效果边界时,可以参考 `tradecatlabs/vibe-coding-cn`。 -知识库入口位于 `.github/context/README.md`。新手从`.github/getting-started-README.md`配置环境;需要处理具体工作时,按需阅读`.github/first-project.md`《如何完成工作》指南,以自选目标编排必要方法并用证据验收(独立可选);冻结原文保存在 `.github/context/gongfa/data.json`;`.github/context/gongfa/README.md#原文文集`只提供索引与历史锚点,对象说明见天、地、玄、黄分阶页。开发者先读 `.github/context/gongfa/README.md#doc-glue-coding`、`.github/context/gongfa/README.md#doc-project-architecture-template` 和 `.github/context/gongfa/README.md#doc-technology-stack`;协作模型读 `.github/context/gongfa/README.md#doc-ai-core-propositions` 与 `.github/context/gongfa/README.md#doc-dao-fa-shu-qi`。逐条身份、来源和初评见 `.github/context/gongfa/README.md` 与 `.github/context/gongfa/data.json`,分阶说明见对应页面;研究档案不随公开仓库分发;外部事实与观察应核对官方或一手来源。 +知识库入口位于 `.github/context/README.md`。新手从`.github/getting-started-README.md`配置环境;需要处理具体工作时,按需阅读`.github/how-to-complete-work.md`《如何完成工作》指南,以自选目标编排必要方法并用证据验收(独立可选);冻结原文保存在 `.github/context/gongfa/data.json`;`.github/context/gongfa/README.md#原文文集`只提供索引与历史锚点,对象说明见天、地、玄、黄分阶页。开发者先读 `.github/context/gongfa/README.md#doc-glue-coding`、`.github/context/gongfa/README.md#doc-project-architecture-template` 和 `.github/context/gongfa/README.md#doc-technology-stack`;协作模型读 `.github/context/gongfa/README.md#doc-ai-core-propositions` 与 `.github/context/gongfa/README.md#doc-dao-fa-shu-qi`。逐条身份、来源和初评见 `.github/context/gongfa/README.md` 与 `.github/context/gongfa/data.json`,分阶说明见对应页面;研究档案不随公开仓库分发;外部事实与观察应核对官方或一手来源。 diff --git a/.github/taxonomy.yml b/.github/taxonomy.yml index fff99299..605bc7ec 100644 --- a/.github/taxonomy.yml +++ b/.github/taxonomy.yml @@ -20,8 +20,8 @@ reading_paths: documents: - .github/getting-started-README.md - .github/context/gongfa/README.md#doc-vibe-coding-experience - - .github/god.md - - .github/first-project.md + - .github/pi-cli-setup.md + - .github/how-to-complete-work.md - .github/context/gongfa/README.md#doc-problem-solving - .github/context/gongfa/README.md#doc-vibe-coding-state-transition - .github/context/gongfa/README.md#doc-glue-coding @@ -54,7 +54,7 @@ reading_paths: - .github/context/gongfa/README.md#doc-development-process - .github/getting-started-README.md - .github/context/gongfa/README.md#doc-vibe-coding-experience - - .github/first-project.md + - .github/how-to-complete-work.md - .github/context/gongfa/README.md#doc-project-architecture-template - .github/context/gongfa/README.md#doc-quality-gates-and-pitfalls - .github/ai-citation-README.md @@ -69,10 +69,10 @@ selection_rules: getting-started: 需要准备 Pi CLI、连接所选模型并验证本机工具调用时读取;《如何完成工作》是独立可选指南,通用经验链接到功法。 documents: getting-started: - - path: .github/god.md + - path: .github/pi-cli-setup.md title: Pi CLI 安装与配置指南 role: 可全文复制给网页版 Chat AI,逐步引导检查或安装 Pi CLI、连接 OpenAI GPT,并由用户在本机验证 Bash 工具调用;区分 CLI 可用、模型回答、工具执行和具体工作完成,验收后停止 - - path: .github/first-project.md + - path: .github/how-to-complete-work.md title: 如何完成工作 role: 可选工作指南:围绕自选目标按需选择方法,实施或观察并以证据验收;不预设具体任务或固定流程 gongfa: diff --git a/.github/test-source-archive.py b/.github/test-source-archive.py index 28d1b217..1326053f 100644 --- a/.github/test-source-archive.py +++ b/.github/test-source-archive.py @@ -144,12 +144,12 @@ class SourceArchiveTest(unittest.TestCase): '../../context/ai-citation/README.md': 'ai-citation-README.md', '../../context/metadata/taxonomy.yml': 'taxonomy.yml', '../../context/prompts/README.md': 'prompts-README.md', - '../../context/getting-started/learning-map.md': 'god.md', + '../../context/getting-started/learning-map.md': 'pi-cli-setup.md', # 单一代码块不产生章节锚点;历史定位保留在输入,当前入口指向整份提示词。 - '../../learning-map.md#milestone-2': 'god.md', - '../getting-started/learning-map.md#ai-guidance-rules': 'god.md', - '../getting-started/learning-map.md#milestone-0': 'god.md', - '../../god.md#milestone-2': 'god.md', + '../../learning-map.md#milestone-2': 'pi-cli-setup.md', + '../getting-started/learning-map.md#ai-guidance-rules': 'pi-cli-setup.md', + '../getting-started/learning-map.md#milestone-0': 'pi-cli-setup.md', + '../../god.md#milestone-2': 'pi-cli-setup.md', '../../context/tool-explanation-template-v1.md': 'tool-explanation-template-v1.md', } for index, link in enumerate(retired_cloud_links): @@ -218,7 +218,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertNotIn('代码不是目录', toc) def test_first_project_discloses_cloud_ai_data_flow(self): - prompt = Path(__file__).with_name('first-project.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('how-to-complete-work.md').read_text(encoding='utf-8') section = prompt.split('## 先选一个安全、可验证的目标', 1)[1].split('## 功法编排:从问题决定方法', 1)[0] required = ( '若使用云端或网页版AI', @@ -229,7 +229,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(all(item in section for item in required)) def test_first_project_cloud_office_files_check_hidden_content(self): - document = Path(__file__).with_name('first-project.md').read_text(encoding='utf-8') + document = Path(__file__).with_name('how-to-complete-work.md').read_text(encoding='utf-8') step1 = document.split('## 第 1 步:定义目标与验收', 1)[1].split('## 第 2 步:拆分并实施最小增量', 1)[0] prompt = step1.split('```text', 1)[1].split('```', 1)[0] self.assertIn( @@ -238,7 +238,7 @@ class SourceArchiveTest(unittest.TestCase): ) def test_first_project_cloud_pdf_overlay_is_not_secure_redaction(self): - document = Path(__file__).with_name('first-project.md').read_text(encoding='utf-8') + document = Path(__file__).with_name('how-to-complete-work.md').read_text(encoding='utf-8') step1 = document.split('## 第 1 步:定义目标与验收', 1)[1].split('## 第 2 步:拆分并实施最小增量', 1)[0] prompt = step1.split('```text', 1)[1].split('```', 1)[0] self.assertIn( @@ -247,7 +247,7 @@ class SourceArchiveTest(unittest.TestCase): ) def test_first_project_goal_selection_includes_nonprescriptive_example(self): - document = Path(__file__).with_name('first-project.md').read_text(encoding='utf-8') + document = Path(__file__).with_name('how-to-complete-work.md').read_text(encoding='utf-8') section = document.split('## 先选一个安全、可验证的目标', 1)[1].split('## 功法编排:从问题决定方法', 1)[0] required = ( '示例(只演示写法,不是预设或必做任务)', @@ -257,14 +257,14 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(all(item in section for item in required)) def test_first_project_prompt_has_optional_pre_ai_method_guess(self): - prompt = Path(__file__).with_name('first-project.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('how-to-complete-work.md').read_text(encoding='utf-8') self.assertIn( '我在看 AI 方案前的暂定判断(可选;问题缺口/候选功法/理由,不确定可写“未知”):【填写】', prompt, ) def test_first_project_prompt_handles_missing_workspace_access_safely(self): - document = Path(__file__).with_name('first-project.md').read_text(encoding='utf-8') + document = Path(__file__).with_name('how-to-complete-work.md').read_text(encoding='utf-8') step1 = document.split('## 第 1 步:定义目标与验收', 1)[1].split('## 第 2 步:拆分并实施最小增量', 1)[0] prompt = step1.split('```text', 1)[1].split('```', 1)[0] required = ( @@ -277,7 +277,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(all(item in prompt for item in required)) def test_first_project_git_preflight_distinguishes_staged_and_unstaged_changes(self): - document = Path(__file__).with_name('first-project.md').read_text(encoding='utf-8') + document = Path(__file__).with_name('how-to-complete-work.md').read_text(encoding='utf-8') step1 = document.split('## 第 1 步:定义目标与验收', 1)[1].split('## 第 2 步:拆分并实施最小增量', 1)[0] required = ( '`git status --short`', @@ -290,7 +290,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(all(item in step1 for item in required), step1) def test_first_project_git_checkpoint_avoids_staging_mixed_file_changes(self): - document = Path(__file__).with_name('first-project.md').read_text(encoding='utf-8') + document = Path(__file__).with_name('how-to-complete-work.md').read_text(encoding='utf-8') git_step = document.split('## 第 6 步:按需保存 Git 检查点', 1)[1].split('## 完成记录', 1)[0] required = ( '同一文件同时包含本次和此前改动', @@ -301,7 +301,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(all(item in git_step for item in required), git_step) def test_first_project_git_checkpoint_confirms_repository_root_and_branch(self): - document = Path(__file__).with_name('first-project.md').read_text(encoding='utf-8') + document = Path(__file__).with_name('how-to-complete-work.md').read_text(encoding='utf-8') git_step = document.split('## 第 6 步:按需保存 Git 检查点', 1)[1].split('## 完成记录', 1)[0] intro = git_step.strip().split('\n\n', 1)[0] required = ( @@ -318,7 +318,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(all(item in intro for item in required), intro) def test_first_project_git_commit_reviews_hooks_before_execution(self): - document = Path(__file__).with_name('first-project.md').read_text(encoding='utf-8') + document = Path(__file__).with_name('how-to-complete-work.md').read_text(encoding='utf-8') git_step = document.split('## 第 6 步:按需保存 Git 检查点', 1)[1].split('## 完成记录', 1)[0] commit_list = next((block for block in git_step.split('\n\n') if '\n4. ' in block), '') item4 = commit_list.split('\n4. ', 1)[1] if '\n4. ' in commit_list else '' @@ -334,7 +334,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(item4 and all(item in item4 for item in required), item4) def test_first_project_pauses_on_unmerged_git_paths(self): - document = Path(__file__).with_name('first-project.md').read_text(encoding='utf-8') + document = Path(__file__).with_name('how-to-complete-work.md').read_text(encoding='utf-8') step1 = document.split('## 第 1 步:定义目标与验收', 1)[1].split('## 第 2 步:拆分并实施最小增量', 1)[0] required = ( '`git status --short` 显示存在未合并/冲突路径', @@ -346,7 +346,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(all(item in step1 for item in required), step1) def test_first_project_project_guidance_does_not_expand_authority(self): - document = Path(__file__).with_name('first-project.md').read_text(encoding='utf-8') + document = Path(__file__).with_name('how-to-complete-work.md').read_text(encoding='utf-8') step1 = document.split('## 第 1 步:定义目标与验收', 1)[1].split('## 第 2 步:拆分并实施最小增量', 1)[0] prompt = step1.split('```text', 1)[1].split('```', 1)[0] required = ( @@ -358,7 +358,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(all(item in prompt for item in required)) def test_first_project_prompt_traces_key_facts_to_nonsensitive_sources(self): - document = Path(__file__).with_name('first-project.md').read_text(encoding='utf-8') + document = Path(__file__).with_name('how-to-complete-work.md').read_text(encoding='utf-8') step1 = document.split('## 第 1 步:定义目标与验收', 1)[1].split('## 第 2 步:拆分并实施最小增量', 1)[0] prompt = step1.split('```text', 1)[1].split('```', 1)[0] required = ( @@ -370,7 +370,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(all(item in prompt for item in required)) def test_first_project_prompt_does_not_follow_out_of_scope_symlinks(self): - document = Path(__file__).with_name('first-project.md').read_text(encoding='utf-8') + document = Path(__file__).with_name('how-to-complete-work.md').read_text(encoding='utf-8') step1 = document.split('## 第 1 步:定义目标与验收', 1)[1].split('## 第 2 步:拆分并实施最小增量', 1)[0] prompt = step1.split('```text', 1)[1].split('```', 1)[0] required = ( @@ -381,13 +381,13 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(all(item in prompt for item in required)) def test_first_project_step1_prompt_lines_are_bounded(self): - document = Path(__file__).with_name('first-project.md').read_text(encoding='utf-8') + document = Path(__file__).with_name('how-to-complete-work.md').read_text(encoding='utf-8') step1 = document.split('## 第 1 步:定义目标与验收', 1)[1].split('## 第 2 步:拆分并实施最小增量', 1)[0] prompt = step1.split('```text', 1)[1].split('```', 1)[0] self.assertLessEqual(max(map(len, prompt.splitlines())), 220) def test_first_project_prompt_uses_relative_nonsensitive_source_locators(self): - document = Path(__file__).with_name('first-project.md').read_text(encoding='utf-8') + document = Path(__file__).with_name('how-to-complete-work.md').read_text(encoding='utf-8') step1 = document.split('## 第 1 步:定义目标与验收', 1)[1].split('## 第 2 步:拆分并实施最小增量', 1)[0] prompt = step1.split('```text', 1)[1].split('```', 1)[0] required = ( @@ -398,7 +398,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(all(item in prompt for item in required)) def test_first_project_prompt_dates_version_sensitive_facts(self): - document = Path(__file__).with_name('first-project.md').read_text(encoding='utf-8') + document = Path(__file__).with_name('how-to-complete-work.md').read_text(encoding='utf-8') step1 = document.split('## 第 1 步:定义目标与验收', 1)[1].split('## 第 2 步:拆分并实施最小增量', 1)[0] prompt = step1.split('```text', 1)[1].split('```', 1)[0] required = ( @@ -410,7 +410,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(all(item in prompt for item in required)) def test_first_project_prompt_excludes_sensitive_workspace_material(self): - document = Path(__file__).with_name('first-project.md').read_text(encoding='utf-8') + document = Path(__file__).with_name('how-to-complete-work.md').read_text(encoding='utf-8') step1 = document.split('## 第 1 步:定义目标与验收', 1)[1].split('## 第 2 步:拆分并实施最小增量', 1)[0] prompt = step1.split('```text', 1)[1].split('```', 1)[0] required = ( @@ -423,7 +423,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(all(item in prompt for item in required)) def test_first_project_prompt_requires_confirmation_before_external_lookup(self): - document = Path(__file__).with_name('first-project.md').read_text(encoding='utf-8') + document = Path(__file__).with_name('how-to-complete-work.md').read_text(encoding='utf-8') step1 = document.split('## 第 1 步:定义目标与验收', 1)[1].split('## 第 2 步:拆分并实施最小增量', 1)[0] prompt = step1.split('```text', 1)[1].split('```', 1)[0] self.assertIn( @@ -432,7 +432,7 @@ class SourceArchiveTest(unittest.TestCase): ) def test_first_project_step2_sanitizes_output_before_reporting(self): - document = Path(__file__).with_name('first-project.md').read_text(encoding='utf-8') + document = Path(__file__).with_name('how-to-complete-work.md').read_text(encoding='utf-8') step2 = document.split('## 第 2 步:拆分并实施最小增量', 1)[1].split('## 第 3 步:按实际方式运行或观察', 1)[0] prompt = step2.split('```text', 1)[1].split('```', 1)[0] self.assertIn( @@ -441,7 +441,7 @@ class SourceArchiveTest(unittest.TestCase): ) def test_first_project_stops_before_unsafe_retry_after_failure(self): - document = Path(__file__).with_name('first-project.md').read_text(encoding='utf-8') + document = Path(__file__).with_name('how-to-complete-work.md').read_text(encoding='utf-8') step2 = document.split('## 第 2 步:拆分并实施最小增量', 1)[1].split('## 第 3 步:按实际方式运行或观察', 1)[0] required = ( '若命令失败或中断', @@ -452,7 +452,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(all(item in step2 for item in required)) def test_first_project_checks_actual_diff_after_file_changes(self): - document = Path(__file__).with_name('first-project.md').read_text(encoding='utf-8') + document = Path(__file__).with_name('how-to-complete-work.md').read_text(encoding='utf-8') step2 = document.split('## 第 2 步:拆分并实施最小增量', 1)[1].split('## 第 3 步:按实际方式运行或观察', 1)[0] required = ( '若修改了文件', @@ -464,28 +464,28 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(all(item in step2 for item in required)) def test_first_project_review_offers_optional_retrieval_before_notes(self): - prompt = Path(__file__).with_name('first-project.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('how-to-complete-work.md').read_text(encoding='utf-8') self.assertIn( '想练习记住方法时,可选地先合上对话和笔记,用自己的话回忆本次的方法选择与证据,再对照原记录补漏;想不起的地方如实标“未知”。这只是低风险的学习练习,不是工作验收,也不是使用本指南的条件。', prompt, ) def test_first_project_review_offers_optional_spaced_retrieval(self): - prompt = Path(__file__).with_name('first-project.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('how-to-complete-work.md').read_text(encoding='utf-8') self.assertIn( '若想再练一次,可隔一段时间后不看记录再次回忆同一方法与证据,再对照补漏;间隔由你决定,不是必做计划。', prompt, ) def test_first_project_offers_optional_code_self_explanation(self): - prompt = Path(__file__).with_name('first-project.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('how-to-complete-work.md').read_text(encoding='utf-8') self.assertIn( '若本次确有代码改动,想练习解释时,可选地挑一处非敏感的小改动,用自己的话说明它做什么、为什么符合一项原定标准;适用时,再手动追踪一个具体输入。然后对照真实差异与验收证据,记录说不清的部分。这是可跳过的学习练习,不要求运行代码,也不替代测试或验收。', prompt, ) def test_god_termux_pkg_upgrade_scope_is_explicit(self): - prompt = Path(__file__).with_name('god.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('pi-cli-setup.md').read_text(encoding='utf-8') m2 = prompt.split('## M2:安装 Pi CLI', 1)[1].split('## M3:验证 CLI', 1)[0] guidance = next((line for line in m2.splitlines() if line.startswith('**Android/Termux:**')), '') required = ( @@ -498,7 +498,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(guidance and all(item in guidance for item in required), guidance) def test_god_termux_pkg_upgrade_keeps_interactive_confirmation(self): - prompt = Path(__file__).with_name('god.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('pi-cli-setup.md').read_text(encoding='utf-8') m2 = prompt.split('## M2:安装 Pi CLI', 1)[1].split('## M3:验证 CLI', 1)[0] guidance = next((line for line in m2.splitlines() if line.startswith('**Android/Termux:**')), '') required = ( @@ -510,7 +510,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(guidance and all(item in guidance for item in required), guidance) def test_god_termux_pi_not_found_uses_official_read_only_diagnostics(self): - prompt = Path(__file__).with_name('god.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('pi-cli-setup.md').read_text(encoding='utf-8') m0 = prompt.split('## M0:检查现状', 1)[1].split('## M1:网络环境', 1)[0] guidance = next((line for line in m0.splitlines() if '`npm prefix -g`' in line), '') required = ( @@ -525,14 +525,14 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(guidance and all(item in guidance for item in required)) def test_god_m0_install_repair_handoff_co_locates_consent_stop_and_evidence(self): - prompt = Path(__file__).with_name('god.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('pi-cli-setup.md').read_text(encoding='utf-8') self.assertIn( '确认未安装或需修复后,先按实际系统说明所选官方安装路线的影响、必要网络目标及恢复方式并等待用户明确同意;拒绝、影响不明或状态仍不清时暂停,不安装。用户同意后,按 M1 只检查该路线需要的网络(代理仍按 M1 条件由用户选择),再按 M2 走当前系统官方安装步骤;完成后按 M3 在同一终端运行 `pi --version`,只有得到版本号才记为 CLI 可用并继续 M4。', prompt, ) def test_god_m2_defers_pi_start_until_m40_review(self): - prompt = Path(__file__).with_name('god.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('pi-cli-setup.md').read_text(encoding='utf-8') m2 = prompt.split('## M2:安装 Pi CLI', 1)[1].split('## M3:验证 CLI', 1)[0] self.assertIn( '安装完成后若出现 `Start pi now? [Y/n]`,明确输入 `n`,不要按 Enter 接受默认启动;先按 M3 核验版本,再到 M4.0 说明目录资源和信任影响后,由用户决定是否启动 Pi。', @@ -540,7 +540,7 @@ class SourceArchiveTest(unittest.TestCase): ) def test_god_m2_windows_user_path_prompt_requires_explicit_consent(self): - prompt = Path(__file__).with_name('god.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('pi-cli-setup.md').read_text(encoding='utf-8') m2 = prompt.split('## M2:安装 Pi CLI', 1)[1].split('## M3:验证 CLI', 1)[0] windows = m2.split('**Windows 原生 PowerShell 官方安装器:**', 1)[1].split( '**仅供已选择的备用路线:**', 1 @@ -557,7 +557,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(windows and all(item in windows for item in required)) def test_god_m2_windows_node_install_prompt_discloses_side_effects_and_consent(self): - prompt = Path(__file__).with_name('god.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('pi-cli-setup.md').read_text(encoding='utf-8') m2 = prompt.split('## M2:安装 Pi CLI', 1)[1].split('## M3:验证 CLI', 1)[0] windows = m2.split('**Windows 原生 PowerShell 官方安装器:**', 1)[1].split( '**仅供已选择的备用路线:**', 1 @@ -578,7 +578,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(windows and all(item in windows for item in required)) def test_god_m2_windows_portable_git_discloses_recursive_replacement_risk(self): - prompt = Path(__file__).with_name('god.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('pi-cli-setup.md').read_text(encoding='utf-8') m2 = prompt.split('## M2:安装 Pi CLI', 1)[1].split('## M3:验证 CLI', 1)[0] windows = m2.split('**Windows 原生 PowerShell 官方安装器:**', 1)[1].split( '**仅供已选择的备用路线:**', 1 @@ -595,7 +595,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(windows and all(item in windows for item in required)) def test_god_m2_windows_node_install_discloses_replacement_of_managed_directory(self): - prompt = Path(__file__).with_name('god.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('pi-cli-setup.md').read_text(encoding='utf-8') m2 = prompt.split('## M2:安装 Pi CLI', 1)[1].split('## M3:验证 CLI', 1)[0] windows = m2.split('**Windows 原生 PowerShell 官方安装器:**', 1)[1].split( '**仅供已选择的备用路线:**', 1 @@ -612,7 +612,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(windows and all(item in windows for item in required)) def test_god_m2_macos_homebrew_node_upgrade_requires_explicit_consent(self): - prompt = Path(__file__).with_name('god.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('pi-cli-setup.md').read_text(encoding='utf-8') m2 = prompt.split('## M2:安装 Pi CLI', 1)[1].split('## M3:验证 CLI', 1)[0] posix = m2.split('**Windows 原生 PowerShell 官方安装器:**', 1)[0] required = ( @@ -628,7 +628,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(posix and all(item in posix for item in required)) def test_god_m2_posix_standalone_node_replacement_requires_local_check(self): - prompt = Path(__file__).with_name('god.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('pi-cli-setup.md').read_text(encoding='utf-8') m2 = prompt.split('## M2:安装 Pi CLI', 1)[1].split('## M3:验证 CLI', 1)[0] posix = m2.split('**Windows 原生 PowerShell 官方安装器:**', 1)[0] required = ( @@ -645,7 +645,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(posix and all(item in posix for item in required)) def test_god_uninstall_managed_root_deletion_requires_local_target_check(self): - prompt = Path(__file__).with_name('god.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('pi-cli-setup.md').read_text(encoding='utf-8') uninstall = prompt.split('## 可选:用户明确要求卸载时', 1)[1].split('## 技术边界', 1)[0] required = ( '官方安装器的 **Uninstall Pi**', @@ -661,7 +661,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(uninstall and all(item in uninstall for item in required)) def test_god_m2_linux_apt_node_upgrade_requires_explicit_consent(self): - prompt = Path(__file__).with_name('god.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('pi-cli-setup.md').read_text(encoding='utf-8') m2 = prompt.split('## M2:安装 Pi CLI', 1)[1].split('## M3:验证 CLI', 1)[0] posix = m2.split('**Windows 原生 PowerShell 官方安装器:**', 1)[0] required = ( @@ -680,7 +680,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(posix and all(item in posix for item in required)) def test_god_m2_windows_portable_git_shellpath_persistence_requires_consent(self): - prompt = Path(__file__).with_name('god.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('pi-cli-setup.md').read_text(encoding='utf-8') m2 = prompt.split('## M2:安装 Pi CLI', 1)[1].split('## M3:验证 CLI', 1)[0] windows = m2.split('**Windows 原生 PowerShell 官方安装器:**', 1)[1].split('**仅供已选择的备用路线:**', 1)[0] required = ( @@ -697,7 +697,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(windows and all(item in windows for item in required)) def test_god_m2_windows_winget_agreements_require_consent(self): - prompt = Path(__file__).with_name('god.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('pi-cli-setup.md').read_text(encoding='utf-8') m2 = prompt.split('## M2:安装 Pi CLI', 1)[1].split('## M3:验证 CLI', 1)[0] windows = m2.split('**Windows 原生 PowerShell 官方安装器:**', 1)[1].split('**仅供已选择的备用路线:**', 1)[0] required = ( @@ -714,7 +714,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(windows and all(item in windows for item in required)) def test_god_m2_linux_standalone_node_xz_dependency_requires_consent(self): - prompt = Path(__file__).with_name('god.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('pi-cli-setup.md').read_text(encoding='utf-8') m2 = prompt.split('## M2:安装 Pi CLI', 1)[1].split('## M3:验证 CLI', 1)[0] posix = m2.split('**macOS/Linux 官方安装器:**', 1)[1].split('**Windows 原生 PowerShell 官方安装器:**', 1)[0] standalone = posix.split('POSIX 安装器在 Node.js/npm 预检未通过', 1)[1].split('macOS 安装器在 Node.js/npm 预检未通过', 1)[0] @@ -732,7 +732,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(standalone and all(item in standalone for item in required)) def test_god_m2_posix_standalone_node_checksum_is_conditional(self): - prompt = Path(__file__).with_name('god.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('pi-cli-setup.md').read_text(encoding='utf-8') m2 = prompt.split('## M2:安装 Pi CLI', 1)[1].split('## M3:验证 CLI', 1)[0] posix = m2.split('**macOS/Linux 官方安装器:**', 1)[1].split('**Windows 原生 PowerShell 官方安装器:**', 1)[0] standalone = posix.split('POSIX 安装器在 Node.js/npm 预检未通过', 1)[1].split('macOS 安装器在 Node.js/npm 预检未通过', 1)[0] @@ -749,28 +749,28 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(standalone and all(item in standalone for item in required)) def test_first_project_optional_transfer_practice_compares_cases_with_evidence_boundary(self): - prompt = Path(__file__).with_name('first-project.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('how-to-complete-work.md').read_text(encoding='utf-8') self.assertIn( '若想练习方法迁移,可自行选一个第二情境(只构想即可,不必开始新工作)。并排写下两情境要解决的问题、约束和可观察的成功证据;比较相似点与关键差异,再说明本次方法哪些可复用、哪些需调整或不适用。理由应能回指本次记录;未在新情境实际验收前,不说迁移已成功。此练习可跳过。', prompt, ) def test_first_project_offers_conditional_regression_first_guidance(self): - prompt = Path(__file__).with_name('first-project.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('how-to-complete-work.md').read_text(encoding='utf-8') self.assertIn( '| 可稳定复现的软件缺陷 | [开发流程](context/gongfa/README.md#doc-development-process);回归测试先行 | 仅当缺陷可稳定复现且项目已有适用测试环境;先确认修复前测试会失败,再做最小修复;若无测试环境,保留复现步骤与原始现象,标“未验证”,不为此搭建或安装工具 | 修复前失败且修复后通过的同一回归测试;否则为复现证据和未验证记录 |', prompt, ) def test_first_project_acceptance_explains_boundary_value_analysis(self): - prompt = Path(__file__).with_name('first-project.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('how-to-complete-work.md').read_text(encoding='utf-8') self.assertIn( '若原定验收标准包含有序范围或阈值,且有可控验证对象,可用边界值分析检查每个边界值及其相邻区间中的最近取值,不必穷举所有输入;记录测试值、预期和实际结果。无可控对象时标“未验证”,不为此搭建测试环境。', prompt, ) def test_first_project_acceptance_requires_oracle_or_unverified_stop(self): - prompt = Path(__file__).with_name('first-project.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('how-to-complete-work.md').read_text(encoding='utf-8') acceptance = prompt.split('## 第 4 步:用证据验收', 1)[1].split( '## 第 5 步:复核并总结迁移方法', 1 )[0] @@ -784,7 +784,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(all(item in acceptance for item in required)) def test_first_project_acceptance_offers_limited_relation_check_without_exact_oracle(self): - prompt = Path(__file__).with_name('first-project.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('how-to-complete-work.md').read_text(encoding='utf-8') acceptance = prompt.split('## 第 4 步:用证据验收', 1)[1].split( '## 第 5 步:复核并总结迁移方法', 1 )[0] @@ -799,7 +799,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(all(item in acceptance for item in required)) def test_first_project_acceptance_refreshes_evidence_after_code_changes(self): - prompt = Path(__file__).with_name('first-project.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('how-to-complete-work.md').read_text(encoding='utf-8') acceptance = prompt.split('## 第 4 步:用证据验收', 1)[1].split( '## 第 5 步:复核并总结迁移方法', 1 )[0] @@ -813,7 +813,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(all(item in acceptance for item in required)) def test_first_project_acceptance_covers_defined_input_categories(self): - prompt = Path(__file__).with_name('first-project.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('how-to-complete-work.md').read_text(encoding='utf-8') acceptance = prompt.split('## 第 4 步:用证据验收', 1)[1].split( '## 第 5 步:复核并总结迁移方法', 1 )[0] @@ -827,7 +827,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(all(item in acceptance for item in required)) def test_first_project_acceptance_checks_defined_condition_combinations(self): - prompt = Path(__file__).with_name('first-project.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('how-to-complete-work.md').read_text(encoding='utf-8') acceptance = prompt.split('## 第 4 步:用证据验收', 1)[1].split( '## 第 5 步:复核并总结迁移方法', 1 )[0] @@ -842,7 +842,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(all(item in acceptance for item in required)) def test_first_project_acceptance_checks_defined_state_sequences(self): - prompt = Path(__file__).with_name('first-project.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('how-to-complete-work.md').read_text(encoding='utf-8') acceptance = prompt.split('## 第 4 步:用证据验收', 1)[1].split( '## 第 5 步:复核并总结迁移方法', 1 )[0] @@ -857,7 +857,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(all(item in acceptance for item in required)) def test_first_project_failure_checks_test_conditions_before_fix(self): - prompt = Path(__file__).with_name('first-project.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('how-to-complete-work.md').read_text(encoding='utf-8') acceptance = prompt.split('## 第 4 步:用证据验收', 1)[1].split( '## 第 5 步:复核并总结迁移方法', 1 )[0] @@ -874,7 +874,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(all(item in acceptance for item in required)) def test_first_project_acceptance_prioritizes_checks_under_constraints(self): - prompt = Path(__file__).with_name('first-project.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('how-to-complete-work.md').read_text(encoding='utf-8') acceptance = prompt.split('## 第 4 步:用证据验收', 1)[1].split( '## 第 5 步:复核并总结迁移方法', 1 )[0] @@ -889,7 +889,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(all(item in acceptance for item in required)) def test_first_project_acceptance_requires_defined_nonfunctional_environment(self): - prompt = Path(__file__).with_name('first-project.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('how-to-complete-work.md').read_text(encoding='utf-8') acceptance = prompt.split('## 第 4 步:用证据验收', 1)[1].split( '## 第 5 步:复核并总结迁移方法', 1 )[0] @@ -902,7 +902,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(all(item in acceptance for item in required)) def test_god_share_gist_copies_may_persist(self): - prompt = Path(__file__).with_name('god.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('pi-cli-setup.md').read_text(encoding='utf-8') m40 = prompt.split('### M4.0:进入 Pi 交互界面', 1)[1].split('### M4.1:验证对话能力', 1)[0] required = ( 'Gist 可被 clone 或 fork', @@ -912,7 +912,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(all(item in m40 for item in required)) def test_god_share_gist_link_is_not_access_control(self): - prompt = Path(__file__).with_name('god.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('pi-cli-setup.md').read_text(encoding='utf-8') m40 = prompt.split('### M4.0:进入 Pi 交互界面', 1)[1].split('### M4.1:验证对话能力', 1)[0] required = ( 'GitHub 将这类 private gist 称为 secret gist', @@ -923,7 +923,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(all(item in m40 for item in required)) def test_god_share_upload_and_destination_are_explicit(self): - prompt = Path(__file__).with_name('god.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('pi-cli-setup.md').read_text(encoding='utf-8') m40 = prompt.split('### M4.0:进入 Pi 交互界面', 1)[1].split('### M4.1:验证对话能力', 1)[0] required = ( 'Pi 的 `/share` 会上传本会话并生成查看链接', @@ -935,7 +935,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(all(item in m40 for item in required)) def test_god_no_tools_route_clarifies_manual_bang_command(self): - prompt = Path(__file__).with_name('god.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('pi-cli-setup.md').read_text(encoding='utf-8') m40 = prompt.split('### M4.0:进入 Pi 交互界面', 1)[1].split('### M4.1:验证对话能力', 1)[0] self.assertIn( 'Pi 交互界面的 `!命令` 是你手动发起的终端命令,不是模型工具调用;输出会进入对话。`--no-tools`不禁止你手动输入它,也不使命令变安全;先审阅命令,并避免会暴露敏感信息的输出。', @@ -943,7 +943,7 @@ class SourceArchiveTest(unittest.TestCase): ) def test_god_prompt_offers_no_tools_model_only_route_with_limits(self): - prompt = Path(__file__).with_name('god.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('pi-cli-setup.md').read_text(encoding='utf-8') self.assertIn( '若只接受模型对话、暂不启用工具,可在本机 `pi --help` 支持时运行 `pi --no-tools --no-extensions`。', prompt, @@ -959,7 +959,7 @@ class SourceArchiveTest(unittest.TestCase): ) def test_god_prompt_offers_read_only_file_analysis_mode(self): - prompt = Path(__file__).with_name('god.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('pi-cli-setup.md').read_text(encoding='utf-8') self.assertIn( '若要让模型读取非敏感项目文件、但不给模型 Bash、Edit 或 Write 工具,并希望本次不连接Pi内置MCP服务器,也不给模型MCP工具,可在本机 `pi --help` 支持时运行 `pi --tools read --no-mcp --no-extensions --no-skills`。', prompt, @@ -982,7 +982,7 @@ class SourceArchiveTest(unittest.TestCase): ) def test_god_read_only_mode_prevents_builtin_mcp_connections(self): - prompt = Path(__file__).with_name('god.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('pi-cli-setup.md').read_text(encoding='utf-8') guidance = next((line for line in prompt.splitlines() if '`pi --tools read' in line), '') required = ( '`pi --tools read --no-mcp --no-extensions --no-skills`', @@ -994,7 +994,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(guidance and all(item in guidance for item in required)) def test_god_bash_only_tool_mode_discloses_remaining_authority(self): - prompt = Path(__file__).with_name('god.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('pi-cli-setup.md').read_text(encoding='utf-8') m40 = prompt.split('### M4.0:进入 Pi 交互界面', 1)[1].split('### M4.1:验证对话能力', 1)[0] guidance = next((line for line in m40.splitlines() if '`pi --tools bash' in line), '') required = ( @@ -1010,7 +1010,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(guidance and all(item in guidance for item in required)) def test_god_bash_only_mode_prevents_builtin_mcp_connections(self): - prompt = Path(__file__).with_name('god.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('pi-cli-setup.md').read_text(encoding='utf-8') m40 = prompt.split('### M4.0:进入 Pi 交互界面', 1)[1].split('### M4.1:验证对话能力', 1)[0] guidance = next((line for line in m40.splitlines() if '`pi --tools bash' in line), '') required = ( @@ -1023,42 +1023,42 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(guidance and all(item in guidance for item in required)) def test_god_read_only_mode_warns_sensitive_files_and_stops_if_present(self): - prompt = Path(__file__).with_name('god.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('pi-cli-setup.md').read_text(encoding='utf-8') self.assertIn( '不要让模型读取 `.env`、凭据文件或个人敏感数据;`read` 不会替你检查或脱敏文件内容,读取内容可能进入模型上下文及 Pi 会话。若目录内含不能交给模型的资料,不要在此目录启动该模式;改用不含该资料的目录或停止。', prompt, ) def test_god_no_session_does_not_claim_cloud_requests_stay_local(self): - prompt = Path(__file__).with_name('god.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('pi-cli-setup.md').read_text(encoding='utf-8') self.assertIn( '使用 OpenAI GPT 时,送入模型上下文的提示和文件内容会发送给 OpenAI 处理。`--no-session` 只影响 Pi 本地会话持久化;它不阻止模型请求,也不控制服务商的数据处理或保留政策。不要发送无权或不愿交给服务商的内容;按当前授权路线和账号核对 OpenAI 官方说明。', prompt, ) def test_god_local_model_route_does_not_guarantee_local_data_processing(self): - prompt = Path(__file__).with_name('god.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('pi-cli-setup.md').read_text(encoding='utf-8') self.assertIn( 'Pi 既支持本机 llama.cpp router,也可配置兼容服务器或代理;“本地模型”名称本身不证明请求只在本机处理。先核实实际服务端点与数据流;未确认前不要发送敏感内容。', prompt, ) def test_god_custom_model_command_values_are_reviewed_before_request(self): - prompt = Path(__file__).with_name('god.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('pi-cli-setup.md').read_text(encoding='utf-8') self.assertIn( '若自定义 `models.json` 并在凭据或请求头值中使用 `!` 命令,Pi 会在模型请求时执行命令且不会缓存;先审核命令及其权限,不要照抄未知指令。', prompt, ) def test_god_prompt_warns_about_mcp_connections_before_pi_start(self): - prompt = Path(__file__).with_name('god.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('pi-cli-setup.md').read_text(encoding='utf-8') self.assertIn( 'MCP 是一种让 Pi 连接服务器并把服务器的工具和资源提供给模型的协议。启动普通 Pi 会话时,所有已启用的 MCP 服务器会在后台自动连接。项目配置 `.pi/mcp.json` 只在授予项目信任后读取;用户级配置默认位于 `~/.pi/agent/mcp.json`,可跨项目生效。stdio 服务器可启动本机进程,HTTP 服务器可能连接远端服务。首次在已有目录启动普通 Pi 或更改 MCP 配置后,先在本机检查两处是否有未知启用项;来源或目标不明时暂停,不要把配置或凭据发送给网页版 Chat AI。', prompt, ) def test_god_m42_requires_the_exact_command_and_stops_on_extra_calls(self): - prompt = Path(__file__).with_name('god.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('pi-cli-setup.md').read_text(encoding='utf-8') self.assertIn( '只有确认 Pi 本次仅执行上方这条 Bash 只读命令并返回 `local shell OK`,才记为通过。', prompt, @@ -1073,7 +1073,7 @@ class SourceArchiveTest(unittest.TestCase): ) def test_god_openai_connectivity_probe_requires_explicit_user_consent(self): - prompt = Path(__file__).with_name('god.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('pi-cli-setup.md').read_text(encoding='utf-8') m41 = prompt.split('### M4.1:验证对话能力', 1)[1].split('### M4.2:验证实际工具调用', 1)[0] guidance = next((line for line in m41.splitlines() if 'api.openai.com/v1/models' in line), '') required = ( @@ -1090,7 +1090,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(guidance and all(item in guidance for item in required)) def test_god_oauth_callback_host_scope_requires_local_review(self): - prompt = Path(__file__).with_name('god.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('pi-cli-setup.md').read_text(encoding='utf-8') m41 = prompt.split('### M4.1:验证对话能力', 1)[1].split('### M4.2:验证实际工具调用', 1)[0] guidance = next((line for line in m41.splitlines() if 'PI_OAUTH_CALLBACK_HOST' in line and '`0.0.0.0`' in line), '') required = ( @@ -1106,14 +1106,14 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(guidance and all(item in guidance for item in required)) def test_god_oauth_update_requires_install_channel_and_official_route(self): - prompt = Path(__file__).with_name('god.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('pi-cli-setup.md').read_text(encoding='utf-8') self.assertRegex( prompt, r'若当前版本没有该选项[^\n]*如选择更新[^\n]*确认现有 Pi 的安装渠道[^\n]*按该渠道官方说明操作[^\n]*渠道不明就暂停[^\n]*不猜更新命令', ) def test_god_openai_model_visibility_does_not_prove_subscription_route(self): - prompt = Path(__file__).with_name('god.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('pi-cli-setup.md').read_text(encoding='utf-8') m41 = prompt.split('### M4.1:验证对话能力', 1)[1].split('### M4.2:验证实际工具调用', 1)[0] guidance = next((line for line in m41.splitlines() if '`OPENAI_API_KEY`' in line), '') required = ( @@ -1126,7 +1126,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(guidance and all(item in guidance for item in required), guidance) def test_god_openai_custom_base_url_requires_local_endpoint_review(self): - prompt = Path(__file__).with_name('god.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('pi-cli-setup.md').read_text(encoding='utf-8') m41 = prompt.split('### M4.1:验证对话能力', 1)[1].split('### M4.2:验证实际工具调用', 1)[0] guidance = next( (paragraph for paragraph in m41.split('\n\n') if 'models.json' in paragraph and '`baseUrl`' in paragraph), @@ -1143,7 +1143,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(guidance and all(item in guidance for item in required), guidance) def test_god_custom_endpoint_discloses_data_recipient_before_use(self): - prompt = Path(__file__).with_name('god.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('pi-cli-setup.md').read_text(encoding='utf-8') m41 = prompt.split('### M4.1:验证对话能力', 1)[1].split('### M4.2:验证实际工具调用', 1)[0] guidance = next( (paragraph for paragraph in m41.split('\n\n') if '内置 `openai` provider 设置 `baseUrl`' in paragraph), @@ -1161,7 +1161,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(guidance and all(item in guidance for item in required), guidance) def test_god_openai_remote_http_base_url_requires_transport_check(self): - prompt = Path(__file__).with_name('god.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('pi-cli-setup.md').read_text(encoding='utf-8') m41 = prompt.split('### M4.1:验证对话能力', 1)[1].split('### M4.2:验证实际工具调用', 1)[0] guidance = next( (paragraph for paragraph in m41.split('\n\n') if '远端' in paragraph and '`baseUrl`' in paragraph and '`http://' in paragraph), @@ -1180,7 +1180,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(guidance and all(item in guidance for item in required), guidance) def test_god_remote_custom_endpoint_preserves_tls_certificate_validation(self): - prompt = Path(__file__).with_name('god.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('pi-cli-setup.md').read_text(encoding='utf-8') m41 = prompt.split('### M4.1:验证对话能力', 1)[1].split('### M4.2:验证实际工具调用', 1)[0] guidance = next((paragraph for paragraph in m41.split('\n\n') if 'NODE_TLS_REJECT_UNAUTHORIZED=0' in paragraph), '') required = ( @@ -1195,7 +1195,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(guidance and all(item in guidance for item in required), guidance) def test_god_models_json_literal_api_key_must_stay_local(self): - prompt = Path(__file__).with_name('god.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('pi-cli-setup.md').read_text(encoding='utf-8') m41 = prompt.split('### M4.1:验证对话能力', 1)[1].split('### M4.2:验证实际工具调用', 1)[0] guidance = next((paragraph for paragraph in m41.split('\n\n') if '`apiKey`' in paragraph and 'models.json' in paragraph), '') required = ( @@ -1208,7 +1208,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(guidance and all(item in guidance for item in required), guidance) def test_god_openai_oauth_hostname_is_checked(self): - prompt = Path(__file__).with_name('god.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('pi-cli-setup.md').read_text(encoding='utf-8') m41 = prompt.split('### M4.1:验证对话能力', 1)[1].split('### M4.2:验证实际工具调用', 1)[0] guidance = next((line for line in m41.splitlines() if line.startswith('- **订阅 OAuth:**')), '') required = ( @@ -1221,7 +1221,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(guidance and all(item in guidance for item in required), guidance) def test_god_oauth_browser_account_must_match_user_choice(self): - prompt = Path(__file__).with_name('god.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('pi-cli-setup.md').read_text(encoding='utf-8') m41 = prompt.split('### M4.1:验证对话能力', 1)[1].split('### M4.2:验证实际工具调用', 1)[0] guidance = next((line for line in m41.splitlines() if line.startswith('- **订阅 OAuth:**')), '') required = ( @@ -1233,7 +1233,7 @@ class SourceArchiveTest(unittest.TestCase): self.assertTrue(guidance and all(item in guidance for item in required), guidance) def test_god_oauth_callback_conflict_has_safe_local_stop_path(self): - prompt = Path(__file__).with_name('god.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('pi-cli-setup.md').read_text(encoding='utf-8') m41 = prompt.split('### M4.1:验证对话能力', 1)[1].split('### M4.2:验证实际工具调用', 1)[0] guidance = next((line for line in m41.splitlines() if '`1455`' in line and 'OAuth state mismatch' in line), '') required = ( @@ -1249,7 +1249,7 @@ class SourceArchiveTest(unittest.TestCase): def test_god_prompt_renders_markdown_with_only_example_code_blocks(self): from markdown_it import MarkdownIt import book_views - prompt = Path(__file__).with_name('god.md').read_text(encoding='utf-8') + prompt = Path(__file__).with_name('pi-cli-setup.md').read_text(encoding='utf-8') markdown = MarkdownIt('commonmark') tokens = markdown.parse(prompt) unrendered_emphasis = [ @@ -1426,10 +1426,20 @@ class SourceArchiveTest(unittest.TestCase): self.assertIn(rendered, html) self.assertEqual(html.count('
'), 5)
         self.assertTrue({'pi-cli-安装与配置指南', 'm0检查现状', '官方资料'}.issubset(
-            book_views._links.markdown_anchors(Path(__file__).with_name('god.md'))))
-        self.assertEqual(book_views.relocated('.github/god.md', 'milestone-2'), ('.github/god.md', ''))
+            book_views._links.markdown_anchors(Path(__file__).with_name('pi-cli-setup.md'))))
+        self.assertEqual(book_views.relocated('.github/god.md', 'milestone-2'),
+                         ('.github/pi-cli-setup.md', ''))
         self.assertEqual(book_views.relocated('.github/first-project.md', 'example'),
-                         ('.github/first-project.md', 'example'))
+                         ('.github/how-to-complete-work.md', 'example'))
+        self.assertEqual(book_views.relocated('.github/context/getting-started/first-project.md', 'example'),
+                         ('.github/how-to-complete-work.md', 'example'))
+
+    def test_getting_started_documents_use_descriptive_filenames(self):
+        root = Path(__file__).parent
+        self.assertTrue((root / 'pi-cli-setup.md').is_file())
+        self.assertTrue((root / 'how-to-complete-work.md').is_file())
+        self.assertFalse((root / 'god.md').exists())
+        self.assertFalse((root / 'first-project.md').exists())
 
     def test_v1_explanations_remain_separate_from_frozen_source_documents(self):
         explanation = {'template_sha256': 'a' * 64, 'items': []}
diff --git a/README.md b/README.md
index de3710be..e7d634c9 100644
--- a/README.md
+++ b/README.md
@@ -19,7 +19,7 @@
   许可证
   交流群
   功法体系:思想、准则、方法与流程
-  Pi CLI 安装与配置指南,供网页版 AI 分步引导
+  Pi CLI 安装与配置指南,供网页版 AI 分步引导
   skills技能大全
   提示词在线表格
   Wiki 导航入口
@@ -48,8 +48,8 @@
 
 ### 🚀 从零开始
 
-1. **从对话到工作:** 将[Pi CLI 安装与配置指南](.github/god.md)全文复制给网页版 Chat AI;先确认系统/终端并复用已安装的 Pi,缺少 CLI 时再按所选安装路线核对网络、安装并验证,之后连接 OpenAI GPT,并通过本机 Pi 的真实工具调用验证基础执行通路;这不代表某项具体工作已完成。
-2. **如何完成工作:** 按需阅读[如何完成工作](.github/first-project.md),围绕自选目标编排必要方法并用证据验收;本指南独立可选,不预设具体任务或要求完成固定流程。
+1. **从对话到工作:** 将[Pi CLI 安装与配置指南](.github/pi-cli-setup.md)全文复制给网页版 Chat AI;先确认系统/终端并复用已安装的 Pi,缺少 CLI 时再按所选安装路线核对网络、安装并验证,之后连接 OpenAI GPT,并通过本机 Pi 的真实工具调用验证基础执行通路;这不代表某项具体工作已完成。
+2. **如何完成工作:** 按需阅读[如何完成工作](.github/how-to-complete-work.md),围绕自选目标编排必要方法并用证据验收;本指南独立可选,不预设具体任务或要求完成固定流程。
 
 
 
diff --git a/llms.txt b/llms.txt
index 10bb6742..317347be 100644
--- a/llms.txt
+++ b/llms.txt
@@ -28,8 +28,8 @@ vibe-coding-cn是以Pi Agent与已授权OpenAI GPT为主体底座的Vibe Coding
 - .github/context/README.md
 - .github/getting-started-README.md
 - .github/context/gongfa/README.md#doc-vibe-coding-experience
-- .github/god.md
-- .github/first-project.md
+- .github/pi-cli-setup.md
+- .github/how-to-complete-work.md
 - .github/context/gongfa/README.md
 - .github/context/gongfa/README.md#doc-ai-core-propositions
 - .github/context/gongfa/README.md#doc-dao-fa-shu-qi