diff --git a/.gitignore b/.gitignore index 8deca55..bf9c198 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,4 @@ Thumbs.db # 本地环境配置(勿提交密钥) .env .env.* +.pouch diff --git a/AGENTS.md b/AGENTS.md index 3eebfbf..0d0d10d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -12,16 +12,14 @@ ## 快速开始 +需要 Python 3、git,以及 Cursor / Claude Code / Codex 或其它兼容 Agent Skills 的 Agent。人类用法见根 [README.md](README.md) 和各 skill 的 `README.md`。用户要代装时按 README 的 [让 Agent 代装](README.md#让-agent-代装) 执行,不要只用 `pouch select`。 + ```bash -# 1. 克隆并关联 git clone https://git.yumee.top/laily/pouch.git ~/.pouch cd ~/.pouch && ./install.sh -# install.sh 会自动把 pouch 项目 skill 安装到所有 Agent -# 2. 安装其他 skill -pouch add declarative-openspec-loop -g - -# 3. 查看状态 +# install.sh 只把 pouch skill 装到所有 Agent;其它 skill 用 select / add +pouch select -g pouch list pouch status ``` @@ -31,19 +29,11 @@ pouch status ## 仓库结构 ``` -skills/ -├── _template/ # 新建 skill 的脚手架 -├── ack/ # 完整 ACK skill,含 references/templates/scripts -├── declarative-openspec-loop/ # 自研 skill,必须含 SKILL.md -│ ├── SKILL.md -│ └── reference.md -├── discussion-notes/ # 讨论沉淀笔记 -│ ├── SKILL.md -│ └── reference.md -pouch/ # CLI 源码(Python 3) -bin/pouch # CLI 入口 -catalog.yaml # pouch 预置 Skill 来源目录 -AGENTS.md # 本文档 +skills/ # 自研 skill(SSOT):每个子目录含 SKILL.md(Agent)和 README.md(人类) +pouch/ # CLI 源码(Python 3) +bin/pouch # CLI 入口 +catalog.yaml # pouch 预置 Skill 来源目录 +AGENTS.md # 本文档 ``` **本仓库包含**:`skills/`、`pouch/`、`bin/pouch`、`catalog.yaml`、`AGENTS.md` @@ -56,16 +46,21 @@ AGENTS.md # 本文档 ### 内置(Builtin) -| Skill | 说明 | -| ---------------------------------------------------------------------- | ------------------------------------------------- | -| [orc](skills/orc/SKILL.md) | ORC 入口:显式编排开发、版本发布与产物任务,支持 Agent 分档 | -| [ack](skills/ack/SKILL.md) | ACK 入口:显式初始化、检查并运行三角色闭环、测试环境、发版与回归 | -| [pouch](skills/pouch/SKILL.md) | 本项目工作流:创建、使用、反馈与更新 builtin skill | -| [declarative-openspec-loop](skills/declarative-openspec-loop/SKILL.md) | 声明式编程循环:用户提供校验方式,Agent 自动 propose/apply/校验并迭代直到通过 | -| [discussion-notes](skills/discussion-notes/SKILL.md) | 讨论沉淀:边讨论边维护 Markdown 笔记,无 .raw.md | +| Skill | 说明 | +| --- | --- | +| [ack](skills/ack/README.md) | 显式初始化、检查并运行三角色闭环:需求 / bug、测试环境、发版与回归 | +| [builder](skills/builder/README.md) | 按统一契约构建和发布 DEB / Docker 镜像 | +| [declarative-openspec-loop](skills/declarative-openspec-loop/README.md) | 你给校验方式,Agent 自动 propose / apply / 校验直到通过 | +| [deployer](skills/deployer/README.md) | 用 Git 里的 Compose 或 Argo CD 清单部署服务 | +| [discussion-notes](skills/discussion-notes/README.md) | 边讨论边维护 Markdown 笔记 | +| [draw-prototype-flow](skills/draw-prototype-flow/README.md) | 把产品想法画成可编辑的 Draw.io 低保真原型和用户动线 | +| [manage-release](skills/manage-release/README.md) | 给已准备好的 commit 发版本:更新说明、tag、可选 Forge Release | +| [memory-distill](skills/memory-distill/README.md) | 任务结束后把可复用结论写入通用记忆和项目记忆 | +| [orc](skills/orc/README.md) | 把开发、发版、DEB / Docker 意图编排成阶段,按档位分发给对应 skill | +| [pouch](skills/pouch/README.md) | 创建、校验、安装和维护 builtin skill | -新建 skill:复制 `skills/_template/` → `skills//`,编辑 `SKILL.md`,在本仓库 commit。 +新建 skill:优先 `pouch create`;或复制 `skills/_template/` → `skills//`,编辑 `SKILL.md` 和 `README.md`,在本仓库 commit。 Skill 需要的稳定规范、模板、示例和脚本直接放在自己的目录中,例如 `skills/ack/references/`、`templates/`、`examples/` 和 `scripts/`。项目初始化只生成 @@ -164,12 +159,6 @@ catalog.yaml ←── pouch add / fetch | **Custom Source** | `~/.local/share/pouch/sources/` 或本地路径 | `pouch source add/fetch` | | **External NPM** | `node_modules/` | `npx skills add` / `skills-npm` | -### 非 Skill 资料分类 - -| 类型 | 位置 | 维护方式 | -| --- | --- | --- | -| **OpenSpec 配置** | `openspec/` | 本仓库 commit;服务于本仓库自身的规格流程 | - ### 多 Agent 路径 @@ -260,7 +249,8 @@ pouch sync ``` skill-name/ -├── SKILL.md # 必需 +├── SKILL.md # 必需,给 Agent +├── README.md # 必需,给人类 ├── reference.md # 可选 ├── examples.md # 可选 └── scripts/ # 可选 @@ -285,7 +275,7 @@ description: >- ### 新建流程 1. `pouch create my-skill --idea "..." --from-project .` -2. Agent 编辑 `~/.pouch/.drafts/my-skill/SKILL.md` +2. Agent 编辑 `~/.pouch/.drafts/my-skill/SKILL.md` 和 `README.md` 3. `pouch check my-skill` 4. 用户确认后执行 `pouch finalize my-skill` 5. `pouch add my-skill -a cursor -g -y` 验证 @@ -341,8 +331,8 @@ Claude Code 对 symlink 支持不稳定:可能无法发现 skill,或写入 | ---------- | --------------------------------- | ---- | | 首次安装 | `git clone ~/.pouch && ~/.pouch/install.sh` | 任意 | | 新建 skill | `pouch create` → Agent 完善 → `check/finalize` | 任意项目 | -| 全局启用 | `pouch install ` | 任意 | -| 项目启用 | `pouch enable ` | 项目目录 | +| 全局启用 | `pouch add -g` | 任意 | +| 项目启用 | `pouch add ` 或 `pouch enable ` | 项目目录 | | 看状态 | `pouch status` | 任意 | | 装社区 skill | `npx skills add owner/repo -g -y` | 任意 | | 更新外部 skill | `pouch fetch ` | 任意 | diff --git a/README.md b/README.md index 521a7f4..505cec9 100644 --- a/README.md +++ b/README.md @@ -2,15 +2,26 @@ 自研 [Agent Skills](https://agentskills.io) 的单一事实来源(SSOT)。仓库、家目录 `~/.pouch` 和 CLI 都叫 **pouch**。Skill 内容与 CLI 在本仓库一并维护。 +人类用法看各 skill 的 `README.md`;`SKILL.md` 是给 Agent 的指令。用户要你代装时,按 [让 Agent 代装](#让-agent-代装) 自己执行,不要只把命令贴回去。 + +## 前置 + +- Python 3、git +- Cursor、Claude Code、Codex,或其它兼容 Agent Skills 的 Agent +- `~/.local/bin` 需要在 `PATH` 里(`install.sh` 会写入 bash / zsh / fish 的 rc,当前 shell 要重开或 `source` 一次才生效) + ## 快速开始 ```bash git clone https://git.yumee.top/laily/pouch.git ~/.pouch cd ~/.pouch -./install.sh # 安装 CLI,并将 pouch 项目 skill 安装到所有 Agent +./install.sh -pouch add declarative-openspec-loop -g -pouch select # 交互式选择并批量安装 +# install.sh 会安装 pouch 命令,并把 pouch 这一个 skill 装到所有 Agent +# 若当前 shell 找不到 pouch:重开终端,或 source 对应 rc + +pouch select # 交互选择要装的 skill(默认当前项目) +pouch select -g # 或装到全局,所有项目都能用 pouch list pouch status ``` @@ -24,10 +35,77 @@ mv ~/.skills ~/.pouch `install.sh` 会安装 `pouch` 命令,并保留 `pouch` 作为旧命令别名。项目里已有的 `.skills.yaml` 仍可读取;新写入使用 `.pouch.yaml`。 +## 让 Agent 代装 + +用户说「帮我安装 pouch」「把 skill 装上」时按本节做。CLI 只认 `~/.pouch`。不要用 `pouch select`(必须交互式 TTY)。不要在未确认时覆盖已有的 `~/.pouch`。 + +### 1. 确认本机 + +需要 `python3` 和 `git`。缺了先说明怎么装,不要继续。 + +### 2. 让 `~/.pouch` 指向本仓库 + +按现状只走一条: + +| 现状 | 动作 | +| --- | --- | +| 当前目录就是这份仓库(有 `install.sh` 和 `skills/`),且没有 `~/.pouch` | `ln -sfn "$(pwd)" "$HOME/.pouch"` | +| `~/.pouch` 已在且含 `skills/`、`install.sh` | 沿用 | +| 只有 `~/.skills` | `mv ~/.skills ~/.pouch` | +| 都没有 | `git clone https://git.yumee.top/laily/pouch.git ~/.pouch`。失败则问用户本地路径或可用 remote | +| `~/.pouch` 在,但不是这份仓库 | 停下问用户,不要删、不要覆盖 | + +### 3. 装 CLI 和 `pouch` skill + +```bash +"$HOME/.pouch/install.sh" +export PATH="$HOME/.local/bin:$PATH" +command -v pouch +pouch status +``` + +`install.sh` 会改 rc,当前会话仍要 `export PATH`。不要让用户重开终端才继续。 + +### 4. 安装用户要的其它 skill + +先 `pouch add --list`。用户没点名就问一次:装哪些、全局还是当前项目。能判断就不要追问。 + +```bash +pouch add -g -y # 全局,所有项目都能用 +pouch add -y # 仅当前项目 +``` + +默认 `pouch add` 装到当前工作目录。cwd 是 pouch 仓库本身时用 `-g`,除非用户就在维护 pouch。用户是在自己的应用仓库里请你代装,才做项目级安装。 + +`install.sh` 已经全局装好 `pouch` skill。其它 skill 不要默认全装。 + +### 5. 验收并告诉用户下一步 + +```bash +pouch status +pouch doctor +``` + +说明:打开 Cursor / Claude Code / Codex 后,按各 skill README 里的示例说话即可。软链异常则 `pouch doctor --fix`。已经装好时只汇报状态,问还要不要加 skill,不要重新 clone。 + +## 装完之后怎么用 + +1. 打开已安装目标的 Agent(Cursor / Claude Code / Codex 等)。 +2. 项目级安装:打开那个项目再说话。全局安装(`-g`):任意项目都可以。 +3. 按对应 skill 的 README,把示例请求发给 Agent。 + +`./install.sh` 只全局安装 `pouch`。其它 skill 都要 `pouch add` 或 `pouch select`。 + +```bash +cd ~/code/my-app +pouch add ack # 当前项目 +pouch add discussion-notes -g # 全局 +``` + ## 仓库结构 ``` -skills/ # 自研 skill(SSOT):每个子目录必须有 SKILL.md +skills/ # 自研 skill(SSOT):每个子目录含 SKILL.md 和 README.md pouch/ # CLI 源码(Python 3) bin/pouch # CLI 入口 catalog.yaml # pouch 预置 Skill 来源目录 @@ -36,7 +114,7 @@ AGENTS.md # 详细规范与架构说明 | 路径 | 说明 | |------|------| -| [skills/](skills/) | 自研 skill,每个子目录含 `SKILL.md`,可附带 references、templates 和 scripts | +| [skills/](skills/) | 自研 skill,每个子目录含给人看的 `README.md` 和给 Agent 的 `SKILL.md` | | [pouch/](pouch/README.md) | 安装、软链、健康检查 CLI | | [catalog.yaml](catalog.yaml) | pouch 预置 Skill 来源目录 | | [AGENTS.md](AGENTS.md) | 设计原则、编写规范、架构详解 | @@ -44,14 +122,19 @@ AGENTS.md # 详细规范与架构说明 ## 自研 Skill | Skill | 说明 | -|-------|------| -| [orc](skills/orc/SKILL.md) | 显式编排开发、版本发布和产物任务,支持 low/mid/high Agent 档位 | -| [ack](skills/ack/SKILL.md) | 显式初始化、检查并运行 ACK 三角色协作及可选交付闭环 | -| [pouch](skills/pouch/SKILL.md) | 在项目中创建、安装、反馈和维护 builtin skill | -| [declarative-openspec-loop](skills/declarative-openspec-loop/SKILL.md) | 声明式编程循环:用户提供校验方式,Agent 自动迭代直到通过 | -| [discussion-notes](skills/discussion-notes/SKILL.md) | 讨论沉淀:边讨论边维护 Markdown 笔记 | +| --- | --- | +| [ack](skills/ack/README.md) | 显式初始化、检查并运行三角色闭环:需求 / bug、测试环境、发版与回归 | +| [builder](skills/builder/README.md) | 按统一契约构建和发布 DEB / Docker 镜像 | +| [declarative-openspec-loop](skills/declarative-openspec-loop/README.md) | 你给校验方式,Agent 自动 propose / apply / 校验直到通过 | +| [deployer](skills/deployer/README.md) | 用 Git 里的 Compose 或 Argo CD 清单部署服务 | +| [discussion-notes](skills/discussion-notes/README.md) | 边讨论边维护 Markdown 笔记 | +| [draw-prototype-flow](skills/draw-prototype-flow/README.md) | 把产品想法画成可编辑的 Draw.io 低保真原型和用户动线 | +| [manage-release](skills/manage-release/README.md) | 给已准备好的 commit 发版本:更新说明、tag、可选 Forge Release | +| [memory-distill](skills/memory-distill/README.md) | 任务结束后把可复用结论写入通用记忆和项目记忆 | +| [orc](skills/orc/README.md) | 把开发、发版、DEB / Docker 意图编排成阶段,按档位分发给对应 skill | +| [pouch](skills/pouch/README.md) | 创建、校验、安装和维护 builtin skill | -ACK 是包含规范、模板与校验脚本的完整 Skill。安装 Skill 后可初始化当前项目状态: +ACK 是包含规范、模板与校验脚本的完整 Skill。安装后可初始化当前项目状态: ```bash pouch init ack @@ -62,11 +145,13 @@ pouch init ack --project ~/app 项目可用自然语言让 `/ack` 把测试环境绑到 deployer、维护发版 profile,并在任务 验证通过后收获回归用例。 +builder 与 deployer 的项目接入走各自 skill 的「初始化」模式,不要 `pouch init builder` 或 `pouch init deployer`。 + 新建 skill: ```bash pouch create my-skill --idea "描述要解决的重复问题" --from-project . -# 由 Agent 完善 ~/.pouch/.drafts/my-skill/SKILL.md +# 由 Agent 完善 ~/.pouch/.drafts/my-skill/SKILL.md 和 README.md pouch check my-skill pouch finalize my-skill pouch add my-skill -g # 全局安装验证 @@ -89,7 +174,7 @@ pouch add -g -a cursor ```yaml skills: - - name: declarative-openspec-loop + - name: ack source: builtin - name: think source: catalog:waza @@ -101,9 +186,9 @@ targets: # 可选,默认 all ``` ```bash -pouch add declarative-openspec-loop +pouch add ack pouch sync -pouch remove declarative-openspec-loop +pouch remove ack ``` ## Catalog 与 Custom Source @@ -133,7 +218,7 @@ npx skills find typescript ``` 本仓库 -├── skills// ←── pouch install / enable +├── skills// ←── pouch add / select ├── catalog.yaml ←── 预置来源发现与 fetch └── pouch/ ←── python3 -m pouch ↑ @@ -159,6 +244,7 @@ npx skills find typescript - [AGENTS.md](AGENTS.md) — 完整规范、多 Agent 路径、编写约定 - [pouch/README.md](pouch/README.md) — CLI 命令参考与开发说明 +- 各 skill 的人类说明见上表 `README.md` ## 参考 diff --git a/openspec/config.yaml b/openspec/config.yaml deleted file mode 100644 index 392946c..0000000 --- a/openspec/config.yaml +++ /dev/null @@ -1,20 +0,0 @@ -schema: spec-driven - -# Project context (optional) -# This is shown to AI when creating artifacts. -# Add your tech stack, conventions, style guides, domain knowledge, etc. -# Example: -# context: | -# Tech stack: TypeScript, React, Node.js -# We use conventional commits -# Domain: e-commerce platform - -# Per-artifact rules (optional) -# Add custom rules for specific artifacts. -# Example: -# rules: -# proposal: -# - Keep proposals under 500 words -# - Always include a "Non-goals" section -# tasks: -# - Break tasks into chunks of max 2 hours diff --git a/pouch/README.md b/pouch/README.md index f7b3cce..fa248c4 100644 --- a/pouch/README.md +++ b/pouch/README.md @@ -201,7 +201,7 @@ pouch doctor -a cursor ```bash cd ~/code/my-app -pouch add declarative-openspec-loop -a cursor -y +pouch add discussion-notes -a cursor -y ``` ### 添加 Catalog Source @@ -251,3 +251,4 @@ pouch/ - [项目 README](../README.md) - [AGENTS.md](../AGENTS.md) +- 各 skill 的人类说明:`skills//README.md` diff --git a/skills/ack/README.md b/skills/ack/README.md index 8a4e139..9435b4f 100644 --- a/skills/ack/README.md +++ b/skills/ack/README.md @@ -1,28 +1,25 @@ # ACK -ACK 是一个显式调用的 Agent Skill,用三种独立角色运行工程协作闭环: +ACK 是显式调用的 Agent Skill,用三种独立角色跑工程协作闭环: -- Coordinator 拆解需求、派发任务并终检。 -- Developer 实现并执行白盒验证。 -- Test 独立执行黑盒复测。 +- Coordinator 拆解需求、派发任务并终检 +- Developer 实现并做白盒验证 +- Test 独立做黑盒复测 -关键约束是验证者不等于实现者。每个任务最多修复三轮,仍未通过时记录为 -`leftover`,然后继续处理其它任务。 +验证者不能等于实现者。每个任务最多修三轮,仍不过就记为 `leftover`,然后继续别的任务。 -测试环境部署由 ACK 触发、**内部调用 deployer** 执行。发版仍写在同一份 -`.pouch/ack/delivery.yaml`。功能或 bug 验证通过后,把黑盒用例收进 -`.pouch/ack/regression.yaml`;之后可以单独跑回归。 +测试环境由 ACK 触发、内部调用 [deployer](../deployer/README.md)。发版写在同一份 `.pouch/ack/delivery.yaml`。功能或 bug 验证通过后,黑盒用例收进 `.pouch/ack/regression.yaml`,之后可以单独跑回归。 -ACK 只在用户显式调用 `/ack` 或 `$ack` 时运行。 +只在你显式说 `/ack` 或 `$ack` 时运行。 -## 使用场景 +## 什么时候使用 | 场景 | 怎么说 | 结果 | | --- | --- | --- | | 初始化 | `/ack 初始化` | 生成并补全 `.pouch/ack/`;缺项按统一格式列出 | | 检查 | `/ack 检查配置` | 只读校验,默认不改文件;测试环境缺 deployer 时转交 | -| 做需求 | `/ack 处理这个需求:…` | 产品文档 + 拆任务 → 确认 → 三角色闭环 | -| 修 bug | `/ack 修这个 bug:…` 或处理飞书收件 | 短描述 + 验收 → 确认(飞书须你点「已确认」)→ 同一闭环 | +| 做需求 | `/ack 处理这个需求:…` | 产品文档 + 拆任务 → 你确认 → 三角色闭环 | +| 修 bug | `/ack 修这个 bug:…` 或处理飞书收件 | 短描述 + 验收 → 你确认(飞书须你点「已确认」)→ 同一闭环 | | 交付配置 | 说明怎么布测试环境 / 怎么发版 | 写入同一份 `delivery.yaml`;测试环境绑定 deployer | | 运行测试环境 | `/ack 重新布测试环境` | 内部加载 deployer,布 `.pouch/deployer/` | | 运行版本发布 | `/ack 发布一个版本` | 按 `intents.release`;stable/生产仍要单独批准 | @@ -32,17 +29,18 @@ ACK 只在用户显式调用 `/ack` 或 `$ack` 时运行。 ## 安装 -全局安装: - ```bash -pouch add ack -g +pouch add ack # 当前项目 +pouch add ack -g # 全局 ``` -或只安装到当前项目: +## 使用前准备 -```bash -pouch add ack -``` +- 项目是 Git 仓库。 +- 自动拉起 Developer / Test worker 时需要 Orca,以及项目里配置好的 Codex、Cursor、Grok 或 OMP。 +- 布测试环境需要同时安装 [deployer](../deployer/README.md),并准备好 SSH 和目标机器的 Docker Compose。 +- 飞书收 bug 是可选的,要在 `project.md` 里配置 `bugIntake`。 +- 不要 `pouch init builder` 或 `pouch init deployer`。测试环境和发版直接对 `/ack` 说;缺 deployer 时 ACK 会转去它的初始化。 ## 初始化项目 @@ -51,7 +49,7 @@ pouch init ack pouch init ack --project ~/code/my-app ``` -初始化后,项目只保存自己的 ACK 状态: +也可以直接说 `/ack 初始化`。初始化后项目只保存自己的状态: ```text .pouch/ack/ @@ -62,271 +60,62 @@ pouch init ack --project ~/code/my-app └── regression.yaml # 默认 cases: [] ``` -不会在项目中复制或链接 ACK Skill。通用规范、模板和脚本始终从已安装的 Skill -目录读取。 +不会把 ACK Skill 复制进项目。规范、模板和脚本始终从已安装的 Skill 目录读取。 -ACK 从当前命令指定的 `--project-root/.pouch/ack/` 定位项目状态,不要求在 -`tasks.yaml` 中持久化 `repoPath` 或 `devWorktree`。自动 worker 的实际工作目录由 -`--worktree` 指定;默认在 `--project-root` 工作,v0.19 起不再配置 `allowedWorktrees` 白名单。 +旧项目如果只有 `project.md` 和 `tasks.yaml`,不要重跑初始化。说 `/ack 检查配置`,授权后再补空的 `knowledge.yaml` 等缺件。 -## Skill 结构 - -```text -skills/ack/ -├── SKILL.md -├── README.md -├── VERSION -├── references/ # 三角色规范、闭环流程和初始化说明 -├── templates/ # project.md、tasks.yaml、knowledge.yaml、delivery.yaml、regression.yaml 模板和 schema -├── examples/ # 完整示例 -└── scripts/ # 状态校验、任务/知识/回归选择、安全验证执行与结构化 worker launcher -``` - -`SKILL.md` 是 Agent 的工作流入口。`references/` 是按需读取的稳定规范; -`.pouch/ack/project.md` 只保存当前项目的命令、路径和权限差异; -`.pouch/ack/tasks.yaml` 保存当前任务状态;`.pouch/ack/knowledge.yaml` 保存跨任务复用、 -已经独立验证的项目知识护栏。 -`.pouch/ack/delivery.yaml` 是测试环境绑定和版本发布的唯一契约;测试环境由 ACK -内部调用 deployer,运行证据记在 `tasks.yaml.deliveryRuns`。 -`.pouch/ack/regression.yaml` 是黑盒回归用例目录,运行证据记在 -`tasks.yaml.regressionRuns`。 - -## 检查项目状态 - -Agent 会从当前 ACK Skill 目录解析校验脚本: - -```bash -python3 /scripts/validate_tasks.py .pouch/ack/tasks.yaml -python3 /scripts/validate_knowledge.py .pouch/ack/knowledge.yaml \ - --tasks .pouch/ack/tasks.yaml -python3 /scripts/validate_delivery.py .pouch/ack/delivery.yaml \ - --tasks .pouch/ack/tasks.yaml --project-root -python3 /scripts/validate_regression.py .pouch/ack/regression.yaml \ - --tasks .pouch/ack/tasks.yaml -``` - -Coordinator 可以按当前任务上下文做确定性推荐: - -```bash -python3 /scripts/select_tasks.py .pouch/ack/tasks.yaml -python3 /scripts/select_tasks.py .pouch/ack/tasks.yaml \ - --task-id BUG-001 - -python3 /scripts/select_knowledge.py .pouch/ack/knowledge.yaml \ - --component web --path web/app.py --tag long-running-service --limit 10 - -python3 /scripts/select_regression.py .pouch/ack/regression.yaml -python3 /scripts/select_regression.py .pouch/ack/regression.yaml \ - --suite full --case-id REG-login-001 -``` - -任务选择器会解析并执行完整任务板的内置语义校验,但只输出 `project`、`summary`、 -默认可工作状态或显式 `--task-id` 命中的任务,以及这些任务引用的 receipt 和 delivery -run。默认最多 20 条,超过预算时显式失败;Agent 不应回退为把完整 `tasks.yaml` 注入 -上下文。 - -默认 JSON 输出会同时给出固定知识引用和已解析的 `verificationTarget.path/args`; -选择器只输出数据,不执行检查。`scope.all=true` 的全项目 active 规则优先占用 -`--limit`;如果全项目规则本身超过预算,选择器会显式失败,不会静默漏派。 - -需要执行知识项引用的检查时,只传 registry ID 给 ACK 的安全执行入口: - -```bash -python3 /scripts/run_verification.py \ - .pouch/ack/knowledge.yaml check-api-contract --project-root -``` - -该入口会在执行前重新校验知识库,只打开一次项目根目录 fd,再从同一个 fd 逐段以 -`O_NOFOLLOW` 打开知识库和检查文件;检查内容复制到匿名、尽可能 sealed 的稳定 -快照,再以结构化 argv 和 `shell=False` 启动。它不接受临时命令或额外参数。 -选择器输出的 path/args 只用于审阅,不应由 Agent 自行拼接执行。Runner 只读取 -项目内无 symlink 的权威 -`.pouch/ack/knowledge.yaml`,不接受替代知识文件或放宽后的项目根。检查进程的 cwd -和 `ACK_PROJECT_ROOT` 都固定到该根 fd;后者是只在检查进程存活期间有效的 -`/proc/self/fd/...` 或 `/dev/fd/...` 路径。原始可读路径另放在 -`ACK_PROJECT_ROOT_DISPLAY`,只能用于日志,不能用于资源访问。Runner 还提供 -`ACK_VERIFICATION_REF` 和 `ACK_VERIFICATION_PATH`;检查脚本必须据此定位资源, -不能依赖 `$0` 或 `__file__` 所在目录,因为实际执行的是匿名快照。 - -知识先由 Developer 或 Test 作为 `candidate` 提名,经独立验证和 Coordinator gate -后才能成为 `active`。Coordinator 按路径、组件、依赖、版本和标签推荐相关知识, -确认后将固定 revision 的 `knowledgeRefs` 写入任务上下文;每轮只派发命中的少量 -条目,不全量注入知识库。 - -旧项目只有 `project.md` 和 `tasks.yaml` 时,不要重跑初始化。由 `/ack` 检查现有 -状态,获得用户授权后补一个空的 `knowledge.yaml`;如果任务板尚未声明知识库, -同时只补 `project.knowledgeFile: .pouch/ack/knowledge.yaml`,再运行跨文件校验。 - -只有 Coordinator 写 `tasks.yaml`、`knowledge.yaml` 和 `regression.yaml`。知识正文 -不能作为自由 shell 执行;关键约束应继续下沉到测试、lint、CI 或正式规范。ACK -不自动修改项目的 `AGENTS.md`、`CLAUDE.md` 或其它 Agent 指令文件。 - -## 配置与运行交付 - -测试环境走 deployer 的项目内布局(通常是 `.pouch/deployer/test`),发版仍用 -delivery profile。可以直接说: - -```text -/ack 测试环境用项目里的 .pouch/deployer/test;发版方式以后再告诉你。 -``` - -ACK 把测试环境写成 `intents.testEnvironment.via: deployer`,把发版写成 -`intents.release` 指向的 profile。`.pouch/deployer/` 还没就绪时,ACK -会转去 deployer 的初始化,而不是自己编 compose。首次配置保持关闭,确认后才启用。 -之后可以说: +## 使用示例 ```text +/ack 初始化 +/ack 检查配置 +/ack 处理这个需求:给后台加导出 CSV +/ack 修这个 bug:保存后列表不刷新。复现:… 期望:… +/ack 处理飞书里待整理的 bug +/ack 测试环境用项目里的 .pouch/deployer/test;发版方式以后再告诉你 /ack 重新布一下测试环境,我要测试 /ack 发布一个版本 -``` - -对应 intent 未配置时先问清楚并写回同一文件,不猜测。运行测试环境时 ACK 加载 -deployer skill,不复制 compose 命令。本地进程启动写在 `project.md`,不算这个 -模式。intent 运行不要求当前有 `verified` 任务;`deliveryRuns.intent` 记录是 -测试环境还是发版。 - -交付配置只允许声明式工具 target 或仓库内可执行脚本,不接受自由 shell,也不保存 -凭据值。任务进入 `verified` 后的常规交付仍按确认过的 profile 执行。默认 -profile 只能停在 `validation_ready` 或 `review_ready`;稳定发布或生产部署必须经过 -对应 approval 步骤。具体契约见 `references/delivery.md`。 - -## 启动 Worker - -worker 的机器配置位于 `tasks.yaml.project.orchestration`:项目显式维护模型 -allowlist、结构化 profile、默认 profile 和允许的 worktree。不得在 `project.md` -或任务里保存完整启动命令、额外 argv 或环境变量。 - -先审阅计划,不产生终端: - -```bash -python3 /scripts/launch_worker.py plan \ - --project-root \ - --task-id \ - --attempt-id -A \ - --role developer \ - --profile-id codex-dev-standard \ - --worktree -``` - -确认后执行 `launch`,并显式绑定刚审阅的 fingerprint: - -```bash -python3 /scripts/launch_worker.py launch \ - --project-root \ - --task-id \ - --attempt-id -A \ - --role developer \ - --profile-id codex-dev-standard \ - --worktree \ - --expected-launch-fingerprint -``` - -launcher 是自动创建 worker 的唯一入口:它从权威任务板重读 profile,构造固定 -argv,忽略调用者 PATH、使用环境 allowlist,并验证真实 Git worktree 注册;然后 -通过仓库外的单次启动记录、terminal-bound nonce/proof 和受限 bootstrap 调用 Orca。 -返回的 receipt 含 `runtimeId`、handle、incarnation、profile hash、slot 和 worktree -identity。Coordinator 将 receipt 追加到顶层 `workerReceipts`,再把 receipt ID -写入任务的 `dispatch.developer` 或 `dispatch.test`,并同步写入本轮 `attemptId`。 -校验器要求 receipt 与当前 ACK task、角色、profile 和 attempt 完全一致;历史 receipt -不能跨任务或跨轮次改挂。 - -v0.10 自动 launcher 仅支持 `read-only` 与 `workspace-write`。full-access、 -Codex bypass、Cursor YOLO/force、Grok `--yolo` / bypassPermissions 和关闭 -sandbox 都会 fail closed;在有可信平台审批或独立签发通道之前,不用项目文件 -伪装成用户授权。Grok worker 由 launcher 固定带 `--always-approve`,避免工具调用 -停在确认框,sandbox 仍必须启用。v0.17 起 `cli: grok` 是一等 worker CLI;`cli: omp` 使用 OMP 的结构化模型、thinking 和 approval-mode 参数,workspace-write 默认 yolo。旧任务板没有结构化 -`project.orchestration` 时仍可读取和手动协作,但不得自动创建 worker。 - -持久化 `receiptHash` 是无密钥 checksum,不是 launcher 身份证明。ACK 只复用同一轮 -内明确空闲、角色/profile/worktree 匹配,并且可以可信清理历史消息、取得新会话身份的 -worker;正在执行、等待回报、状态不明或关联未完成任务的 worker 不复用。由于当前 -Orca 没有可验证的历史消息清理接口,Orca 派发仍重新 `plan` 并用 expected fingerprint -启动 fresh worker。 -fingerprint 只校验完整计划没有漂移,不是一次性令牌;成功后不得用同一 fingerprint -重复启动,结果不确定时必须先 reconcile。 -若创建或关闭回执不完整,或外部 launch record 状态无法可靠持久化,launcher 会返回 -`indeterminate/reconcile-required`;必须先核对 record 与 Orca live state,不能 -直接重试。 - -Coordinator 最后标记整轮任务完成后,会关闭所有只关联 `verified` 任务的 worker -终端。仍关联 `blocked`、`failed_retest`、`leftover`、其它未完成任务或未解决环境事件 -的终端继续保留且不设置 TTL;receipt 与测试证据不会随终端删除。 - -## 开始一个需求 - -初始化完成后可以直接说: - -```text -/ack 处理这个需求:<一句话需求> -``` - -Coordinator 会先读取项目状态和 `references/kickoff.md`,生成产品文档、任务拆分与 -可观测验收信号;用户确认后才派发实现和复测。任务 `verified` 后会把本轮黑盒路径 -收进 `.pouch/ack/regression.yaml`,确认后才写入。 - -## 修复 bug - -可以直接说: - -```text -/ack 修这个 bug:<现象、复现、期望> -``` - -Coordinator 写短问题说明、复现步骤和可观测验收,不写大 PRD;你确认后再派发。 -Developer 先补会失败的用例再修,后续闭环与做需求相同。 - -配了飞书 `bugIntake` 时,飞书是审核前的唯一协作区。你只需维护标题、详细描述和 -附件;Coordinator 整理问题说明、期望效果和验收标准并写回飞书。你针对当前 -revision 审核通过,并亲自把状态改成「已确认」之前,不创建任务、不派 worker。 - -```text -/ack 处理飞书里待整理的 bug -``` - -## 运行回归 - -平时做需求和修 bug 结束后,ACK 按本轮内容更新 `.pouch/ack/regression.yaml`。 -之后可以单独跑: - -```text /ack 回归 /ack 跑 full 回归 /ack 回归 REG-login-001 +/ack 修这些回归失败 ``` -ACK 先按 deployer 布测试环境,再派独立 Test 按用例用浏览器或 API 执行。失败只 -报告,不会自动开修;要修再说 `/ack 修这些回归失败`。默认跑 smoke。细则见 -`references/regression.md`。 - -首次配置交付可以说: +首次配发版也可以一次说清: ```text /ack 更新项目交付配置:用 make build-deb 构建 DEB,发布到 preview APT 仓库, 部署到 test-server 并跑健康检查;完成后创建 PR,停在 review_ready 给我审核。 ``` -之后处理需求时只需在确认计划中选择 profile: +之后做需求时只要在确认计划里选 profile: ```text -/ack 处理这个需求:<一句话需求>。任务验证通过后执行 review profile。 +/ack 处理这个需求:…。任务验证通过后执行 review profile。 ``` -ACK 会自动读取 `delivery.yaml`,无需再逐步提醒它构建、上传、部署或开 PR;目标或 -权限发生漂移、缺少凭据、进入 stable/production approval 时才停下来请求决策。 +## Agent 会做什么 + +1. 初始化或检查 `.pouch/ack/`,缺项按统一格式列出;不从 README/CI 猜测并启用交付或知识。 +2. 做需求:先写产品文档、任务拆分和可观测验收;修 bug 只写短说明、复现和验收。你确认后再派 Developer 和独立 Test。 +3. 需要测试环境时加载 deployer,不自己编 compose,也不把本地 `npm run dev` 当成测试环境。 +4. 任务 `verified` 后提议把本轮黑盒路径写入回归目录,你确认后才写。 +5. 发版读同一份 `delivery.yaml`。默认最多停在 `validation_ready` 或 `review_ready`;稳定发布或生产部署必须再经过对应批准。 +6. 回归失败只报告,不会自动开修。 +7. 未获授权不提交、不推送、不创建终端、不部署,也不改项目的 `AGENTS.md` / `CLAUDE.md`。 + +飞书收件时,你维护标题、详细描述和附件。Coordinator 整理问题说明、期望和验收并写回飞书。你针对当前 revision 审核通过,并亲自把状态改成「已确认」之前,不创建任务、不派 worker。 + +## 如何判断完成 + +- 初始化:五个状态文件齐,报告为完成,或列出待配置项和下一步。 +- 需求 / bug:任务变为 `verified`,或三轮后记为 `leftover`;回归目录有本轮用例,或明确「无回归」。 +- 测试环境:目标环境容器 Up,健康检查通过。 +- 发版:停在约定档位;stable / 生产有单独批准记录。 +- 回归:列出通过和失败的用例;失败不会被自动拿去修。 ## 版本 -当前 Skill 版本见 `VERSION`。新项目在 `tasks.yaml` 中以合法 SemVer 记录 -`ackVersion`。从 `0.10.0` 起,`project.orchestration` 与顶层 `workerReceipts` 必须 -同时存在;从 `0.11.0` 起,新项目还会生成默认关闭的 `delivery.yaml`,并在任务板声明 -`project.deliveryFile` 与 `deliveryRuns`;从 `0.13.0` 起,Coordinator 使用 -`select_tasks.py` 获取有预算的任务上下文,不再把完整任务板注入模型;从 `0.16.0` 起, -`delivery.yaml` 可用 `intents.testEnvironment` 与 `intents.release` 把测试环境部署和 -版本发布写成用户可单独触发的操作;从 `0.17.0` 起,结构化 worker 路由支持 -`cli: grok`(与 Codex、Cursor 并列);从 `0.18.0` 起支持 OMP 的 -`cli: omp` profile(精确 provider/model、thinking 与 approval-mode);从 `0.17.1` 起 Grok worker argv 固定带 -`--always-approve`,sandbox 仍必开;从 `0.19.0` 起 `intents.testEnvironment` 改为 -deployer 绑定,ACK 内部调用 deployer skill 布测试环境,并增加 -`.pouch/ack/regression.yaml` 与「运行回归」模式。旧的测试环境 profile ID 字符串不再 -执行,需要迁到 `{via: deployer, env: }`。旧项目可以不迁移回归目录而继续使用 -原闭环。旧项目的 `kitVersion` 可以继续读取,但建议迁移为 `ackVersion`。 +当前 Skill 版本见 `VERSION`。新项目在 `tasks.yaml` 里记 `ackVersion`。 + +从 0.19.0 起,测试环境写成 `{via: deployer, env: }`,回归目录是 `.pouch/ack/regression.yaml`。旧的测试环境 profile ID 字符串不再执行,需要迁过去。旧项目可以不迁回归目录,继续用原来的闭环。旧的 `kitVersion` 仍可读,建议改成 `ackVersion`。 diff --git a/skills/builder/README.md b/skills/builder/README.md index dc6241e..9ef85ef 100644 --- a/skills/builder/README.md +++ b/skills/builder/README.md @@ -14,6 +14,23 @@ 只构建不上传时明确说明即可;上传永远需要你显式授权。 +## 安装 + +```bash +pouch add builder # 当前项目 +pouch add builder -g # 全局 +``` + +不要 `pouch init builder`。对新项目说「用 builder 初始化」。 + +## 使用前准备 + +- Python 3 和 `make`。 +- DEB 轨道需要 `dpkg-deb`;Docker 轨道需要 Docker 和 buildx。 +- 发布时在项目根 `.env.builder` 填写仓库地址和 token(不要写进 `.env`,也不要进 git)。 +- 正式版本号由 [manage-release](../manage-release/README.md) 打 annotated tag;builder 只读当前 HEAD。 +- 脏工作树默认拒绝发布。 + ## 项目接入契约 对新项目说「用 builder 初始化」。Agent 会探测轨道、按 @@ -98,6 +115,22 @@ detached HEAD 用 `detached`,CI 可注入 `BUILD_BRANCH` / `CI_COMMIT_BRANCH` 用 builder 发布多平台 linux/amd64,linux/arm64 镜像。 ``` +## Agent 会做什么 + +1. 初始化:探测 DEB / Docker 轨道,写出 `makefile.builder` 和 `.env.builder` 骨架,不改你已有的 `Makefile` 或 `.env`。 +2. 检查:只跑 `scripts/check.py --ready`,不改文件。 +3. 构建:走 `make -f makefile.builder`;只获构建授权时不走会自动上传的目标。 +4. 发布:先校验产物,再上传。缺发布键、未授权、或可能覆盖同版本时停下问你。 + +Docker 只有你点名镜像时才走。token 不会写进输出、提交或回复。 + +## 如何判断完成 + +- 初始化:`check.py --ready` 的构建项 PASS。只缺发布键算部分完成,仍可构建、不能上传。 +- 构建:产物路径、规范版本、架构与 `make -f makefile.builder version` 一致。 +- 发布:HTTP 成功或远端 digest 对得上;回复里有包名或镜像引用、SHA-256 / digest、源 commit。 +- 测试包不会通过无参 `apt upgrade` 盖住正式包。 + ## 脚本一览 | 脚本 | 用途 | diff --git a/skills/declarative-openspec-loop/README.md b/skills/declarative-openspec-loop/README.md new file mode 100644 index 0000000..2b5d4ff --- /dev/null +++ b/skills/declarative-openspec-loop/README.md @@ -0,0 +1,55 @@ +# declarative-openspec-loop + +你提供「怎样算符合预期」的校验方式,Agent 按 OpenSpec 走 propose → apply → 校验,不通过就分析原因再迭代,直到通过。 + +## 什么时候使用 + +- 已经能说清目标,也有办法判断结果对不对,希望 Agent 自动做到通过为止。 +- 会说「声明式编程」「按预期循环」「做到校验通过」。 +- 不适合:还在选型、还没有校验手段、只想改一小处且自己盯着看。 + +## 安装 + +```bash +pouch add declarative-openspec-loop # 当前项目 +pouch add declarative-openspec-loop -g # 全局 +``` + +## 使用前准备 + +- 本机已安装 [openspec](https://openspec.dev/) CLI。 +- 当前 Agent 已安装 OpenSpec 的三个子 skill:`openspec-explore`、`openspec-propose`、`openspec-apply-change`。 +- 你必须给出校验方式,缺了 Agent 会先问,不会空跑。可用下面任意组合: + - 校验命令,退出码 0 即通过,比如 `make test-one2` + - 预期文档,里面有校验项表 + - 清单:日志关键字、输出文件、数值容差 + - 自由描述:Agent 会先归纳成可执行检查,向你确认后再跑 + +## 使用示例 + +```text +按声明式循环做:让登录失败时返回统一错误码。 +校验:跑 pytest tests/test_login.py,全部 green 即通过。最多 3 轮。 +``` + +```text +目标:拟合轮廓与 docs/tmp/expect_desc.md 一致。 +校验:make test-one2,且日志覆盖文档「校验项」表全部 8 项。 +``` + +## Agent 会做什么 + +1. 记下 change 名称和校验方式,写到 `docs/tmp//expectation.md`。 +2. 必要时先探索;然后 propose 出 proposal / design / tasks,每个任务尽量带验收。 +3. apply 实现,再跑你给的校验。 +4. 失败按原因分级:小 bug 直接修;任务遗漏就补 tasks;方向错了才改设计。默认最多 5 轮(你可改上限)。同一错误连续 2 轮会停下来问你。 +5. 通过后给出变更摘要和思路,过程记录留在 `docs/tmp//`。 + +不会在没校验方式时开跑,也不会到上限后自己放弃或无限重试。 + +## 如何判断完成 + +- 你指定的校验命令退出码 0,或校验项全部满足。 +- Agent 给出变更文件列表和思路。 +- `docs/tmp//` 里有 `expectation.md`、每轮 `iteration_*.md` 和校验原始输出。 +- 到上限或反复失败时停下,并说明当前进度和未通过项,而不是假装完成。 diff --git a/skills/deployer/README.md b/skills/deployer/README.md index 270b904..8dd11cb 100644 --- a/skills/deployer/README.md +++ b/skills/deployer/README.md @@ -22,6 +22,15 @@ - 需要一张「哪台机器跑哪些服务」的清单 - 镜像要进 Kubernetes,走 Argo CD:改 GitOps、开 MR、合并后部署 +## 安装 + +```bash +pouch add deployer # 当前项目 +pouch add deployer -g # 全局 +``` + +不要 `pouch init deployer`。对新项目说「用 deployer 初始化」。 + ## 使用前准备 - Compose:本机 Python 3、`rsync`、`ssh`;目标机器 Docker Compose v2;`~/.ssh/config` 免密(或 agent) @@ -50,6 +59,7 @@ web1 能出网,直接让它从 https://... 把包拉下来装 # 项目内环境 给这个项目建好 .pouch/deployer,prod 和 test 分别放到两台机器上 把 test 环境重新部署一下 +本机测试镜像已经有了,直接重启,别 sync prod 的 compose 加个 redis,改完发上去 # Argo CD @@ -62,8 +72,8 @@ GitOps 我已经 clone 在 ../infra-gitops,用那个目录开 MR 1. 读服务/环境目录(及共享的父目录)的 `_config.yaml`,确定目标机器和远程路径; 项目内布局从 `.pouch/deployer/` 自动发现,无需额外配置 -2. 用 skill 自带脚本把本地目录同步到远程(rsync,自动排除 `data/`、`_data/`) -3. 在远程执行对应的 `docker compose` 操作(启动 / 重建 / 升级 / 重启) +2. 目标是本机且镜像已在本机 docker:不 sync、不 SSH,在该环境目录直接 `docker compose` +3. 否则用 skill 自带脚本把本地目录同步到远程(rsync,自动排除 `data/`、`_data/`),再远程 `docker compose`(启动 / 重建 / 升级 / 重启) 4. deb 包安装走独立脚本:scp 上传到暂存目录后远程 apt 安装,失败自动修依赖 5. 同步后查看容器状态和日志确认生效 6. 只针对你指定的那一个服务操作,不会批量动整台机器 @@ -78,8 +88,8 @@ GitOps 我已经 clone 在 ../infra-gitops,用那个目录开 MR ## 如何判断完成 -- 脚本输出显示同步完成、远程命令执行成功 -- `ps` 显示容器 Up、`logs` 无报错;升级后镜像 tag 与配置一致 +- 本机:`docker compose ps` 容器 Up。远程:sync 成功且 `remote.py ps` 容器 Up +- `logs` 无报错;升级后镜像 tag 与配置一致 - deb 安装后 `ssh dpkg -l` 能看到目标包,服务能正常启动 - 域名/端口类服务能 curl 通 - Argo CD:给出 MR 链接;合入后 Application Synced,域名/healthz 可访问 diff --git a/skills/deployer/SKILL.md b/skills/deployer/SKILL.md index d45f749..366441b 100644 --- a/skills/deployer/SKILL.md +++ b/skills/deployer/SKILL.md @@ -19,10 +19,10 @@ description: >- - 初始化、接入 deployer,或给新项目建测试/生产环境:执行「初始化」。 - 检查 `.pouch/deployer`、node、compose 是否齐全:执行「检查」。 -- 部署、同步、升级、重启、装 deb、新增/下线服务:执行「Compose 操作」。发现不了服务或解析不出 node 时停止,转入「初始化」。不要静默初始化。 +- 部署、重新部署、同步、升级、重启、布测试环境、装 deb、新增/下线服务:执行「Compose 操作」。发现不了服务或解析不出 node 时停止,转入「初始化」。不要静默初始化。 - ArgoCD / GitOps / 开 MR 部署:执行「Argo CD」。步骤见 [argocd.md](references/argocd.md)。 - 两者都有且意图不清:先问。 -- 不适用:单机 docker、Nomad、常规 `kubectl apply`、构建并推送镜像(走 builder)。 +- 不适用:没有 `.pouch/deployer/` 的随手 `docker compose`、Nomad、常规 `kubectl apply`、构建并推送镜像(走 builder)。本机 node 仍走本 skill,镜像已在本机则跳过 sync。 ## 边界 @@ -66,11 +66,22 @@ python3 -I -S /scripts/deploy/check.py --project ## 被 ACK 调用 -ACK 的「运行测试环境」和回归前布环境会加载本 skill,对 `.pouch/deployer/`(通常是 `test`)按「Compose 操作」执行。ACK 只负责何时布、把访问地址写入 `deliveryRuns`;不要把本 skill 的脚本复制进 ACK。生产环境、Argo CD 合入和节点级批量仍须用户明确要求。 +ACK 的「运行测试环境」和回归前布环境会加载本 skill,按「Compose 操作」的默认路径布测试环境。ACK 只负责何时布、把访问地址写入 `deliveryRuns`;不要把本 skill 的脚本复制进 ACK。生产环境、Argo CD 合入和节点级批量仍须用户明确要求。 ## Compose 操作 -读 [compose.md](references/compose.md)。用 `list.py` 摸底,再按意图对**单个服务**执行 sync/up/recreate/upgrade/restart。解析 `_config.yaml` 见 [config-reference.md](references/config-reference.md)。sync 报错但 ssh 正常时,按 compose.md 的 NAS 兜底处理。每次操作后 `remote.py ps` / `logs` 验证。 +重启 / 重新部署 / 同步 / 布测试环境走默认路径。不要读 compose.md、不要初始化、不要读 Makefile。 + +1. 在项目根执行:`python3 -I -S /scripts/deploy/list.py` +2. 只操作**一个**服务:用户点名的 env;「测试」→ `test`,没有 `test` 就用非 `prod` 的那个。未点名 `prod` 不要动它。 +3. 不要改 compose tag、不要构建镜像、不要看其它环境。 +4. 本机镜像:node 的 ssh `HostName` 是 `127.0.0.1`/`localhost`,且 `docker image inspect` 看得到 compose 里的 tag → **不要** `sync.py` / `remote.py`。进 `.pouch/deployer//` 执行 `docker compose up -d --force-recreate`,再 `ps`。完。 +5. 否则才 sync + remote:`python3 -I -S /scripts/deploy/sync.py ` 然后 `python3 -I -S /scripts/deploy/remote.py recreate`。只要重启:`remote.py restart`。 +6. 远程路径验证:`remote.py ps`;异常再 `logs`。完。 + +compose 用 `image:` 且用户说刚合并了代码:现有 tag 对不上这次提交时,**一句问**要不要先重建镜像,然后停。不要自己改 tag、不要走 builder。 + +新增/下线、deb、镜像 tag 升级、NAS 失败:再读 [compose.md](references/compose.md)。字段见 [config-reference.md](references/config-reference.md)。 ## Argo CD diff --git a/skills/deployer/references/compose.md b/skills/deployer/references/compose.md index d27d48c..cdeae69 100644 --- a/skills/deployer/references/compose.md +++ b/skills/deployer/references/compose.md @@ -81,6 +81,8 @@ python3 /scripts/deploy/sync.py | 意图 | 命令 | |------|------| +| 本机已有镜像(node 是 localhost,image 已在本机 docker) | 不要 sync。在 env 目录 `docker compose up -d --force-recreate` | +| 重新部署远程环境 | `sync.py && remote.py recreate` | | 只同步文件,不动容器 | `sync.py ` | | 应用 compose/配置变更 | `sync.py && remote.py up` | | 改配置后强制重建 | `remote.py recreate`(配合前置 sync) | @@ -88,7 +90,7 @@ python3 /scripts/deploy/sync.py | 仅重启,不同步文件 | `remote.py restart` | | 排查 | `remote.py ps` / `remote.py logs` | -若项目有 Makefile 封装,命令形如 `make deploy TGT=<服务路径>`。没有 Makefile 时直接调 python 脚本,不要新建封装层。 +脚本一律 `python3 -I -S /scripts/deploy/.py`。有 `make deploy TGT=` 才用 Makefile;没有就直接调脚本,不要读 Makefile 去发明封装。 `sync.py` 使用 `rsync -avz --delete`;本机无 rsync 时 tar over SSH 兜底。运行时数据必须放在默认排除的 `data/`、`_data/`,或 compose 挂载的远程绝对路径,否则会被清掉。 diff --git a/skills/deployer/scripts/deploy/deb.py b/skills/deployer/scripts/deploy/deb.py index 7e0e77e..cde6bee 100755 --- a/skills/deployer/scripts/deploy/deb.py +++ b/skills/deployer/scripts/deploy/deb.py @@ -31,7 +31,11 @@ import subprocess import sys from pathlib import Path -from lib import ( +_SCRIPT_DIR = Path(__file__).resolve().parent +if str(_SCRIPT_DIR) not in sys.path: + sys.path.insert(0, str(_SCRIPT_DIR)) + +from lib import ( # noqa: E402 project_root, run_remote, scp_base_args, diff --git a/skills/deployer/scripts/deploy/list.py b/skills/deployer/scripts/deploy/list.py index 8f4ed40..61aacea 100755 --- a/skills/deployer/scripts/deploy/list.py +++ b/skills/deployer/scripts/deploy/list.py @@ -6,8 +6,13 @@ from __future__ import annotations import os import sys from collections import defaultdict +from pathlib import Path -from lib import discover_services, project_root +_SCRIPT_DIR = Path(__file__).resolve().parent +if str(_SCRIPT_DIR) not in sys.path: + sys.path.insert(0, str(_SCRIPT_DIR)) + +from lib import discover_services, project_root # noqa: E402 def main() -> int: diff --git a/skills/deployer/scripts/deploy/remote.py b/skills/deployer/scripts/deploy/remote.py index 2c95302..2532fe5 100755 --- a/skills/deployer/scripts/deploy/remote.py +++ b/skills/deployer/scripts/deploy/remote.py @@ -20,8 +20,13 @@ import argparse import os import subprocess import sys +from pathlib import Path -from lib import project_root, run_remote, service_info +_SCRIPT_DIR = Path(__file__).resolve().parent +if str(_SCRIPT_DIR) not in sys.path: + sys.path.insert(0, str(_SCRIPT_DIR)) + +from lib import project_root, run_remote, service_info # noqa: E402 REMOTE_COMMANDS = { "up": "docker compose up -d", diff --git a/skills/deployer/scripts/deploy/sync.py b/skills/deployer/scripts/deploy/sync.py index 7e4577d..9fa5fc2 100755 --- a/skills/deployer/scripts/deploy/sync.py +++ b/skills/deployer/scripts/deploy/sync.py @@ -16,8 +16,13 @@ import shlex import shutil import subprocess import sys +from pathlib import Path -from lib import DEFAULT_BASE_PATH, project_root, rsync_ssh_args, service_info, ssh_cmd +_SCRIPT_DIR = Path(__file__).resolve().parent +if str(_SCRIPT_DIR) not in sys.path: + sys.path.insert(0, str(_SCRIPT_DIR)) + +from lib import DEFAULT_BASE_PATH, project_root, rsync_ssh_args, service_info, ssh_cmd # noqa: E402 def sync_directory(info: dict) -> int: diff --git a/skills/discussion-notes/README.md b/skills/discussion-notes/README.md new file mode 100644 index 0000000..46b4f10 --- /dev/null +++ b/skills/discussion-notes/README.md @@ -0,0 +1,57 @@ +# discussion-notes + +边讨论边把可复用结论写进项目里的 Markdown 笔记。笔记是活的:理解变了就改,不另存聊天稿。 + +## 什么时候使用 + +- 要进入讨论模式、沉淀到文档、整理笔记、单开文档。 +- 适合学习概念、做技术选型、把讨论变成可回顾的结论。 +- 不适合:一次性问答、必须进 skill 记忆库的沉淀(用 `memory-distill`)、也不要用来当会议逐字稿。 + +说「结束讨论」或「不用记了」就退出;之后不再自动改笔记。 + +## 安装 + +```bash +pouch add discussion-notes # 当前项目 +pouch add discussion-notes -g # 全局 +``` + +## 使用前准备 + +- 指定笔记路径,或接受默认 `000inbox/.md`(按 Obsidian 收件箱习惯)。 +- 有明确话题名更好;没有的话 Agent 会问一次。 +- 笔记写在当前项目仓库内。默认不 git commit。 + +## 使用示例 + +```text +进入讨论模式,记到 000inbox/podman-vs-docker.md:公司 Debian VM 上容器运行时选 Podman 还是 Docker。 +``` + +```text +讨论 Quadlet 是什么,单开一篇概念笔记,并链到刚才的选型文档。 +``` + +```text +这轮不用记,先只回答。 +``` + +```text +结束讨论。 +``` + +## Agent 会做什么 + +1. 确认路径:你指定的文件,或默认 `000inbox/.md`。新话题新建,续聊改已有文件。 +2. 按内容选结构:选型/决策,或概念/原理。模板见 [reference.md](reference.md)。 +3. 每轮先用中文回答你,再更新笔记里的结论、对比、约束;纠正旧理解时直接改,不留错误版本。 +4. 只写可复用知识,不把问答全文抄进文档,不创建 `.raw.md`。 +5. 你说结束时,可选加一节「更新」:搞懂了、纠正了、待动手。 + +## 如何判断完成 + +- 约定路径上有一份正在维护的 `.md`,结构能看出结论而不是聊天记录。 +- 本轮新结论已经写进对应章节;过时说法被改掉,而不是追加在文末。 +- 没有出现 `xxx.raw.md`,也没有未经确认的 git commit。 +- 退出讨论后,Agent 不再自动改那份笔记。 diff --git a/skills/draw-prototype-flow/README.md b/skills/draw-prototype-flow/README.md index 44aece7..466f61a 100644 --- a/skills/draw-prototype-flow/README.md +++ b/skills/draw-prototype-flow/README.md @@ -8,6 +8,13 @@ - 已有 `.drawio` 原型,希望补齐跳转、异常态、权限或规则说明。 - 需要一张能用于产品评审、开发对齐和测试设计的产品说明板。 +## 安装 + +```bash +pouch add draw-prototype-flow # 当前项目 +pouch add draw-prototype-flow -g # 全局 +``` + ## 使用前准备 最好提供产品目标、目标用户、核心任务和已有需求材料。缺少细节时,Agent 会先列出必要假设;只有关键范围无法判断时才会询问。 @@ -34,4 +41,4 @@ ## 如何判断完成 -最终会得到可在 diagrams.net/Draw.io 打开的 `.drawio` 源文件。核心任务应能从入口走到结果,每个关键按钮有明确去向,异常状态有恢复动作,原型、动线和规格使用同一套页面与状态 ID。 +最终会得到可在 diagrams.net/Draw.io 打开的 `.drawio` 源文件。你指定路径就用指定路径,没指定时 Agent 会在项目里给出文件名。核心任务应能从入口走到结果,每个关键按钮有明确去向,异常状态有恢复动作,原型、动线和规格使用同一套页面与状态 ID。 diff --git a/skills/manage-release/README.md b/skills/manage-release/README.md index caf16cb..00a519d 100644 --- a/skills/manage-release/README.md +++ b/skills/manage-release/README.md @@ -4,6 +4,13 @@ 版本文件、worktree、分支、PR/MR 和合并。普通发布优先走“更新说明 + annotated tag”的 短路径;只有发布要求修改仓库内容时,才进入准备版本的分支流程。 +## 安装 + +```bash +pouch add manage-release # 当前项目 +pouch add manage-release -g # 全局 +``` + ## 使用前准备 - 项目已经是 Git 仓库,并配置了可访问的远端。 diff --git a/skills/memory-distill/README.md b/skills/memory-distill/README.md index aff63e8..123711e 100644 --- a/skills/memory-distill/README.md +++ b/skills/memory-distill/README.md @@ -12,6 +12,13 @@ memory-distill 提炼一下刚刚 ack 执行过程中可以沉淀的知识。 也会响应「沉淀记忆」「回顾刚才记下来」「更新记忆」等说法。 +## 安装 + +```bash +pouch add memory-distill # 当前项目 +pouch add memory-distill -g # 全局 +``` + ## 使用前准备 通常不用准备路径。Agent 会: diff --git a/skills/orc/README.md b/skills/orc/README.md index 416598f..4311b92 100644 --- a/skills/orc/README.md +++ b/skills/orc/README.md @@ -11,6 +11,15 @@ ORC 是显式调用的薄路由器:只把开发、版本发布、DEB 和 Docke 只做单一领域任务时可以直接调用对应 Skill;ORC 不替代它们的安全规则。 +## 安装 + +```bash +pouch add orc # 当前项目 +pouch add orc -g # 全局 +``` + +`$orc` / `/orc` 只在显式调用时运行。下游阶段还需要已安装 `$ack`、`$manage-release` 或 `$builder`。 + ## 使用前准备 - Orca 正在运行并启用了 orchestration。 diff --git a/skills/pouch/README.md b/skills/pouch/README.md index c936d67..2ef59c7 100644 --- a/skills/pouch/README.md +++ b/skills/pouch/README.md @@ -1,7 +1,6 @@ # pouch -`pouch` 用于创建、维护、安装和发布团队自研的 Agent Skill。Skill 的唯一来源位于 -`~/.pouch/skills//`,安装到各 Agent 时使用软链接。 +创建、维护、安装和发布团队自研的 Agent Skill。唯一来源在 `~/.pouch/skills//`,装到各 Agent 时用软链。 ## 什么时候使用 @@ -11,6 +10,25 @@ - 想检查并修复 skill 软链接。 - 想优化某个已有 skill 的结构,减少点中后灌进上下文的内容。 +## 使用前准备 + +- 已把本仓库 clone 到 `~/.pouch` 并跑过 `./install.sh`(会把本 skill 装到所有 Agent)。 +- Python 3;`~/.local/bin` 已加入 `PATH`。 +- 至少一种 Agent:Cursor、Claude Code、Codex,或 agents 标准目录。 +- 要推到远端时,本仓库的 git remote 可写。 + +CLI 命令细节见仓库里的 [pouch/README.md](../../pouch/README.md)。 + +## 使用示例 + +```text +帮我把「评审 PR 时按这份清单走」做成一个自研 skill。 +pouch 帮我检查 discussion-notes 这个 skill。 +pouch 帮忙优化 ack 这个 skill 结构,减少 token 浪费。 +把 ack 装到当前项目的 Cursor。 +检查一下 skill 软链,坏了就修。 +``` + ## 创建一个 skill ```bash @@ -32,6 +50,8 @@ pouch check my-skill pouch finalize my-skill ``` +转正不会自动 commit、push 或安装。 + ## 优化已有 skill 的结构 skill 能用但正文太长、所有模式写在一份 `SKILL.md` 里,或点中后把用不到的参考一并读进上下文时: @@ -40,42 +60,62 @@ skill 能用但正文太长、所有模式写在一份 `SKILL.md` 里,或点 pouch 帮忙优化 ack 这个 skill 结构,减少 token 浪费 ``` -Agent 会先测量该 skill 的体积,再按分层加载改 SSOT:`SKILL.md` 只留路由和全模式边界,细节按条件读 `references/`。不会为了缩字删掉发版/部署一类的安全限制。改完仍需 `pouch check` 通过。 +Agent 会先测量该 skill 的体积,再按分层加载改 SSOT:`SKILL.md` 只留路由和全模式边界,细节按条件读 `references/`。不会为了缩字删掉发版、部署一类的安全限制。改完仍需 `pouch check` 通过。 不要对社区 catalog skill 的安装目录直接改;那些不是本仓库的 SSOT。 ## 提交和发布 -只提交: - ```bash pouch publish skills/my-skill -m "add my-skill" -``` - -提交并推送: - -```bash pouch publish skills/my-skill -m "add my-skill" --push ``` -## 安装 +## 安装与维护 -安装到当前项目的 Codex: +`./install.sh` 会执行 `pouch bootstrap`,把本 skill 全局装到所有 Agent。也可以随时重跑: ```bash -pouch add my-skill -a codex -y +pouch bootstrap ``` -安装到全局 Codex: +安装其它 skill: ```bash -pouch add my-skill -a codex -g -y +pouch add my-skill -a codex -y # 当前项目的 Codex +pouch add my-skill -a codex -g -y # 全局 Codex +pouch select # 交互多选,默认当前项目 +pouch select -g # 交互多选,装到全局 ``` +项目状态初始化(目前用于 ack): + +```bash +pouch init ack +pouch init ack --project ~/app +``` + +builder / deployer 不要 `pouch init`,对 Agent 说「用 builder / deployer 初始化」。 + +软链出问题: + +```bash +pouch status +pouch doctor +pouch doctor --fix +``` + +## Agent 会做什么 + +1. 创建草稿到 `~/.pouch/.drafts/`,按你的想法完善 `SKILL.md` 和给人看的 `README.md`。 +2. 跑 `pouch check`;你确认后再 `finalize` 到 `skills/`。 +3. 安装只建指向 SSOT 的软链,不复制文件。默认装当前项目;只有你明确要求时才加 `-g`。 +4. 优化结构时先测量再改 SSOT,不删发版、部署类安全限制。 +5. 未要求时不 commit、不 push、不全局安装。 + ## 如何判断完成 - `pouch check ` 输出校验通过。 - 正式 skill 同时包含 `SKILL.md` 和 `README.md`。 - `pouch status` 或 `pouch doctor` 显示目标软链接正常。 - 优化结构时:审计报告有前后体积,安全限制仍在 `SKILL.md`,没有为缩字删掉模式。 - diff --git a/tests/test_deployer_check.py b/tests/test_deployer_check.py index 58e5c4d..4600911 100644 --- a/tests/test_deployer_check.py +++ b/tests/test_deployer_check.py @@ -2,6 +2,8 @@ from __future__ import annotations import importlib.util import os +import subprocess +import sys import tempfile import unittest from io import StringIO @@ -10,8 +12,10 @@ from unittest import mock REPO_ROOT = Path(__file__).resolve().parents[1] -CHECK_PY = REPO_ROOT / "skills" / "deployer" / "scripts" / "deploy" / "check.py" -LIB_PY = REPO_ROOT / "skills" / "deployer" / "scripts" / "deploy" / "lib.py" +DEPLOY_SCRIPTS = REPO_ROOT / "skills" / "deployer" / "scripts" / "deploy" +CHECK_PY = DEPLOY_SCRIPTS / "check.py" +LIST_PY = DEPLOY_SCRIPTS / "list.py" +LIB_PY = DEPLOY_SCRIPTS / "lib.py" lib_spec = importlib.util.spec_from_file_location("deployer_lib", LIB_PY) assert lib_spec is not None and lib_spec.loader is not None @@ -55,6 +59,43 @@ class DeployerCheckTests(unittest.TestCase): self.assertIn("scripts/deploy/check.py", skill) self.assertIn("不要写假 node", skill) + def test_skill_documents_redeploy_happy_path(self) -> None: + skill = (REPO_ROOT / "skills" / "deployer" / "SKILL.md").read_text( + encoding="utf-8" + ) + compose_section = skill.split("## Compose 操作", 1)[1].split("## Argo CD", 1)[0] + self.assertIn("不要读 compose.md", compose_section) + self.assertIn("remote.py recreate", compose_section) + self.assertIn("一句问", compose_section) + self.assertIn("没有 `test` 就用非 `prod` 的那个", compose_section) + self.assertIn("不要** `sync.py` / `remote.py`", compose_section) + self.assertIn("docker compose up -d --force-recreate", compose_section) + self.assertNotIn( + "读 [compose.md](references/compose.md)。用 `list.py` 摸底", + compose_section, + ) + + def test_list_py_isolated_mode_imports_lib(self) -> None: + with tempfile.TemporaryDirectory() as temp: + project = Path(temp) + root = project / ".pouch" / "deployer" + env = root / "test" + env.mkdir(parents=True) + (root / "_config.yaml").write_text("node: my-vps\n", encoding="utf-8") + (env / "compose.yaml").write_text( + "services:\n web:\n image: nginx\n", encoding="utf-8" + ) + proc = subprocess.run( + [sys.executable, "-I", "-S", str(LIST_PY)], + cwd=str(project), + capture_output=True, + text=True, + check=False, + ) + self.assertEqual(proc.returncode, 0, proc.stderr + proc.stdout) + self.assertIn("test", proc.stdout) + self.assertNotIn("No module named 'lib'", proc.stderr) + def test_missing_layout_fails(self) -> None: with tempfile.TemporaryDirectory() as temp: project = Path(temp)