@weotro/dx 0.1.16 → 0.1.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -4
- package/lib/codex-initial.js +2 -0
- package/package.json +1 -1
- package/skills/ask_3th/SKILL.md +27 -0
- package/skills/{ask_cc/scripts/ask_cc.py → ask_3th/scripts/ask_3th.py} +3 -3
- package/skills/delegate_3th/SKILL.md +87 -0
- package/skills/delegate_3th/scripts/__pycache__/delegate_3th.cpython-314.pyc +0 -0
- package/skills/{delegate-cc/scripts/delegate_cc.py → delegate_3th/scripts/delegate_3th.py} +10 -8
- package/skills/{delegate-cc/scripts/test_delegate_cc.py → delegate_3th/scripts/test_delegate_3th.py} +68 -46
- package/skills/project-agent-standards/SKILL.md +82 -0
- package/skills/project-agent-standards/agents/openai.yaml +6 -0
- package/skills/project-agent-standards/assets/development-standards.md +49 -0
- package/skills/project-agent-standards/assets/dx-development-workflow.md +46 -0
- package/skills/project-agent-standards/assets/follow-up-issues.md +9 -0
- package/skills/project-agent-standards/assets/github/ISSUE_TEMPLATE/issue.md +27 -0
- package/skills/project-agent-standards/assets/github/pull_request_template.md +27 -0
- package/skills/ship-issue-pr/SKILL.md +36 -83
- package/skills/ask_cc/SKILL.md +0 -30
- package/skills/delegate-cc/SKILL.md +0 -66
- /package/skills/{ask_cc → ask_3th}/agents/openai.yaml +0 -0
- /package/skills/{delegate-cc → delegate_3th}/agents/openai.yaml +0 -0
- /package/skills/{delegate-cc → delegate_3th}/scripts/__pycache__/delegate_cc.cpython-314.pyc +0 -0
- /package/skills/{delegate-cc → delegate_3th}/scripts/__pycache__/test_delegate_cc.cpython-314.pyc +0 -0
package/README.md
CHANGED
|
@@ -307,12 +307,13 @@ dx cache clear -Y
|
|
|
307
307
|
- `~/.codex/skills` 中包内管理的同名非软链接 skill 会被清理;已有软链接不会按旧副本删除。
|
|
308
308
|
- 从包内移除的历史 skill 会在 `~/.agents/skills`、`~/.claude/skills`、`~/.codex/skills` 中一并清理。
|
|
309
309
|
- 不属于包内管理的其他用户自有 skill 目录会保留。
|
|
310
|
-
-
|
|
311
|
-
-
|
|
310
|
+
- `ask_3th` 用于向第三方咨询,`delegate_3th` 用于委托第三方执行。可显式调用,也可由已授权的 `ship-issue-pr` 流程调用。
|
|
311
|
+
- 运行时判断由这两个技能内部完成:Codex 宿主调用 Claude,Claude Code 宿主调用 Codex。调用失败后立即使用 fresh sub-agent 接续,返回结果时说明实际执行者与回退原因。
|
|
312
|
+
- `dx initial` 不安装 Python、Claude CLI 或 Codex 插件,也不修改认证配置。
|
|
312
313
|
|
|
313
|
-
|
|
314
|
+
从 `ask_cc` / `delegate-cc` 升级:运行 `dx initial` 后旧技能目录会被清理,请将技能调用改为 `ask_3th` / `delegate_3th`。Claude 通道的脚本路径分别改为 `~/.agents/skills/ask_3th/scripts/ask_3th.py` 和 `~/.agents/skills/delegate_3th/scripts/delegate_3th.py`。脚本调用失败统一返回 `fallback_required`,不再自动轮换模型或返回 `continuation_required` / `next_model`;由技能执行者启动 fresh sub-agent 并等待完成。`--timeout` 仍是无活动告警阈值。
|
|
314
315
|
|
|
315
|
-
Issue/PR 交付统一使用 `ship-issue-pr`:在 Codex 中调用 `$ship-issue-pr`,在 Claude Code 中调用 `/ship-issue-pr
|
|
316
|
+
Issue/PR 交付统一使用 `ship-issue-pr`:在 Codex 中调用 `$ship-issue-pr`,在 Claude Code 中调用 `/ship-issue-pr`。该技能只调用咨询或委托接口、验收结果并记录执行说明,运行时和回退决策封装在依赖技能内部。
|
|
316
317
|
|
|
317
318
|
升级 dx 后再次运行 `dx initial`,会整体更新 `~/.agents/skills/ship-issue-pr/`,并清理已移除的技能和独立引用文件。现有调用统一改为 `ship-issue-pr`。Claude 的软链接直接读取同一份更新;入口同时声明 Codex 和 Claude 的显式调用策略。外部 Claude CLI 或 Codex 插件仍需自行安装并完成认证,目录兼容不代表外部通道已可用。
|
|
318
319
|
|
package/lib/codex-initial.js
CHANGED
|
@@ -13,6 +13,8 @@ const REMOVED_AGENT_REFERENCES = ['ship-issue-pr-core.md']
|
|
|
13
13
|
// 这些名字需要在 ~/.agents、~/.claude、~/.codex 三处彻底清理(软链或真实目录都清)。
|
|
14
14
|
// 将来从 skills/ 删除新的 skill 时,把它追加到这里即可。
|
|
15
15
|
const DELETED_SKILLS = [
|
|
16
|
+
'ask_cc',
|
|
17
|
+
'delegate-cc',
|
|
16
18
|
'oo-ship-issue-pr',
|
|
17
19
|
'cc-ship-issue-pr',
|
|
18
20
|
'autospec',
|
package/package.json
CHANGED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ask_3th
|
|
3
|
+
description: 显式调用 ask_3th 或被已授权流程调用时,向第三方提问、咨询或获取独立审查意见。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# ask_3th
|
|
7
|
+
|
|
8
|
+
向第三方获取答案或第二意见,咨询与审查只读。调用方提供问题、必要事实、源码或 diff、约束和预期输出;运行时选择、调用与失败回退由本技能负责,调用方只接收最终结果和执行说明。
|
|
9
|
+
|
|
10
|
+
## 执行流程
|
|
11
|
+
|
|
12
|
+
1. 整理自包含的问题材料,排除凭据。审查材料覆盖请求范围,证据不足时先补充,不假定咨询者拥有当前对话。
|
|
13
|
+
2. 读取 [delegate_3th](../delegate_3th/SKILL.md),使用其 `consult` 模式完成运行时判断:Codex 宿主调用 Claude,Claude Code 宿主调用 Codex。按相应通道调用,咨询不授予写权限。
|
|
14
|
+
3. 第三方调用失败时,立即执行该技能的 fresh sub-agent 回退流程,等待实质答案后返回。回退在本技能内部完成,不把中间的 `fallback_required` 当作最终答复交给调用方。
|
|
15
|
+
4. 核实答案回应原问题,按依赖技能的返回契约交付答案、实际执行者及回退说明。独立审查使用未参与实现或修复的全新会话。
|
|
16
|
+
|
|
17
|
+
用户要求修改代码或执行任务时,转入 `delegate_3th` 的 `task` 模式,沿用已有任务范围与授权。
|
|
18
|
+
|
|
19
|
+
## Claude 通道脚本
|
|
20
|
+
|
|
21
|
+
仅在上述路由选择 Claude 时使用当前技能目录的 `scripts/ask_3th.py`;它固定为咨询模式,调用细节与失败状态由 `delegate_3th` 维护。脚本自身不能启动宿主 sub-agent,收到失败状态后由执行本技能的 agent 完成回退。
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
python3 "$HOME/.agents/skills/ask_3th/scripts/ask_3th.py" --prompt-file /绝对路径/问题.txt
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
`--timeout` 是无活动告警阈值(默认 120 秒),不是答复截止时间。通过宿主异步工具持续读取同一会话;静默或单次等待超时本身不算调用失败。
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
2
|
+
"""第三方技能的 Claude 咨询入口;统一实现位于 delegate_3th。"""
|
|
3
3
|
|
|
4
4
|
from pathlib import Path
|
|
5
5
|
import sys
|
|
6
6
|
|
|
7
|
-
sys.path.insert(0, str(Path(__file__).resolve().parents[2] / "
|
|
8
|
-
from
|
|
7
|
+
sys.path.insert(0, str(Path(__file__).resolve().parents[2] / "delegate_3th" / "scripts"))
|
|
8
|
+
from delegate_3th import ask, main
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
if __name__ == "__main__":
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: delegate_3th
|
|
3
|
+
description: 显式调用 delegate_3th 或被已授权流程调用时,委托第三方执行任务;内部选择 Claude 或 Codex,失败后由 fresh sub-agent 接续并返回结果。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# delegate_3th
|
|
7
|
+
|
|
8
|
+
本技能负责第三方运行时路由、调用、失败回退及验收。调用方提供任务并接收最终结果,不需要选择 CLI、模型或接管方式。`ask_3th` 使用这里的 `consult` 模式;委托开发工作使用 `task` 模式。
|
|
9
|
+
|
|
10
|
+
## 1. 准备交接
|
|
11
|
+
|
|
12
|
+
遵循宿主指令、当前任务要求与已有授权、目标项目适用的 AGENTS.md。保留现有认证,任务授权不因切换执行者而扩大,权限拒绝不能靠回退绕过。
|
|
13
|
+
|
|
14
|
+
- **咨询 `consult`**:提供问题、事实、源码或 diff、约束与预期输出,只读;Claude CLI 不开放工具,Codex 通道与回退执行者仅允许必要的只读检索。
|
|
15
|
+
- **执行 `task`**:任务书包含工作目录、目标、责任文件或模块、项目指令、已有成果、验收标准和实际验证命令。告知执行者还有其他协作者,保留他人改动,只处理分配范围。
|
|
16
|
+
|
|
17
|
+
执行前检查 `git status --short`、相关 diff 和未跟踪文件,记录基线。分配互不重叠的文件;需要隔离时使用独立 worktree,并带入任务所需的未提交版本。原执行者仍在工作时,其他执行者不修改其责任文件。
|
|
18
|
+
|
|
19
|
+
将必要上下文写入本次临时 UTF-8 任务文件,排除凭据。默认只授权本地实现与验证;调用方明确委托独立 Issue 的完整交付时,任务书须带上该授权与 `ship-issue-pr` 流程,才可执行对应 Git/GitHub 操作。
|
|
20
|
+
|
|
21
|
+
## 2. 在技能内部选择运行时
|
|
22
|
+
|
|
23
|
+
依据当前会话宿主和实际暴露的工具判断,不根据模型名称或本机安装了哪些 CLI 猜测,也不要求调用方选择。
|
|
24
|
+
|
|
25
|
+
| 当前宿主 | 第三方通道 |
|
|
26
|
+
| --- | --- |
|
|
27
|
+
| Codex | 下文 Claude CLI |
|
|
28
|
+
| Claude Code | 下文 Codex 插件 |
|
|
29
|
+
| 宿主无法确定或对应通道缺失 | 直接进入 fresh sub-agent 回退 |
|
|
30
|
+
|
|
31
|
+
每次请求只尝试选定的第三方一次。调用失败后立即回退,不换另一个 Claude 模型、不重试另一条外部通道。单次等待超时、静默告警或任务尚未返回不等于失败;用户取消则停止,不启动接续任务。
|
|
32
|
+
|
|
33
|
+
### Claude CLI
|
|
34
|
+
|
|
35
|
+
需要 `python3` 和已认证的 `claude`;`dx initial` 只同步技能文件。使用当前技能目录的脚本,默认安装示例:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
# 咨询,无活动告警阈值默认 120 秒。
|
|
39
|
+
python3 "$HOME/.agents/skills/delegate_3th/scripts/delegate_3th.py" --prompt-file /绝对路径/问题.txt
|
|
40
|
+
|
|
41
|
+
# 执行,无活动告警阈值默认 900 秒。
|
|
42
|
+
python3 "$HOME/.agents/skills/delegate_3th/scripts/delegate_3th.py" --mode task --cwd /绝对路径/工作区 --prompt-file /绝对路径/任务.txt
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
默认请求 `claude-fable-5-1`。兼容参数 `--start-model` 仅选择本次任务请求的模型,不构成重试链。需要运行验证命令时按已有授权追加具体的 `--allow-command '仓库实际验证命令'`,可重复传入。
|
|
46
|
+
|
|
47
|
+
执行模式开放 `Read,Glob,Grep,Edit,Write,Bash`,使用 `acceptEdits`,无法获批的工具请求自动拒绝;现有权限规则继续生效,允许命令不是独立沙箱。两种模式关闭 hooks、MCP 和技能,因此任务书必须包含必要项目规则。脚本默认仅执行本地开发;完整交付等超出该边界的任务直接进入 fresh sub-agent,由其承接明确授权。
|
|
48
|
+
|
|
49
|
+
通过宿主异步工具保留会话 ID 并持续读取结果,至少每 60 秒汇报有意义的进度。`--timeout` 只控制无活动告警,不自动终止任务。脚本通过输出字节和 Git 跟踪及未忽略文件的变化观察活动;忽略目录产物需另查,观测不可用不代表停滞。
|
|
50
|
+
|
|
51
|
+
脚本 stdout 返回单个 JSON:`ok` 表示咨询已返回,`review_required` 表示任务报告待验收,`fallback_required` 表示立即进入下文回退。脚本只报告失败,启动宿主 sub-agent 和等待结果是本技能执行者的职责。
|
|
52
|
+
|
|
53
|
+
### Codex 插件
|
|
54
|
+
|
|
55
|
+
使用当前 Claude Code 会话实际暴露的 Codex 插件能力:任务或咨询可用 `Agent(subagent_type: "codex:codex-rescue")`;普通审查可用 companion 的 `review`,挑战方案假设可用 `adversarial-review`。选择符合当前请求的一条通道,只读或写入范围写入任务书。
|
|
56
|
+
|
|
57
|
+
companion 使用实际安装路径;需要定位时仅检查当前 Claude 配置目录对应的 marketplace/cache,以 `scripts/codex-companion.mjs --help` 核实参数,不硬编码缓存版本。审查示例:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
node "<plugin-root>/scripts/codex-companion.mjs" review --wait --base "<actual-base>"
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
保存 job/agent ID、工作目录与输出位置,异步等待同一任务。插件缺失、启动失败、认证或额度错误、非零退出、明确失败报告或无效结果均进入回退。
|
|
64
|
+
|
|
65
|
+
## 3. 失败后立即交给 fresh sub-agent
|
|
66
|
+
|
|
67
|
+
fresh sub-agent(refresh subagent)指本次新建、独立上下文的执行者,不复用当前 agent 或此前的实现/审查会话。即使本技能当前由 sub-agent 执行,也应新建执行者,不能直接由它自称 fresh 后接手。
|
|
68
|
+
|
|
69
|
+
1. 确认原调用及其写进程已停止;仍在运行时先检查会话、子命令和权限等待,确认实际失败或无法推进后终止并核实停止。用户取消不触发回退。
|
|
70
|
+
2. 检查现有 diff、测试与外部副作用,将已完成成果和剩余工作加入任务书,避免从头重放。保留原权限限制与只读/写入边界。
|
|
71
|
+
3. 立即创建一个使用宿主默认模型的全新 sub-agent:Codex 使用 `spawn_agent`,设置 `fork_turns: "none"`;Claude Code 使用新的 `Agent(subagent_type: "general-purpose")`,不 resume 旧会话。传入自包含任务书,要求直接处理本次失败调用的剩余工作,不将同一工作再次交给 `ask_3th` / `delegate_3th` 或外部 CLI,避免递归回退。完整交付中的后续独立咨询/审查仍按交付流程调用技能。独立审查者不得是原实现者。
|
|
72
|
+
4. 等待该 sub-agent 完成并验收其结果,再向调用方返回。若 sub-agent 工具不可用、达到嵌套限制或回退也失败,如实返回未完成项与具体阻塞;不冒充已接管或已完成,也不无限创建新 agent。
|
|
73
|
+
|
|
74
|
+
## 4. 验收与返回
|
|
75
|
+
|
|
76
|
+
咨询确认获得实质答案;执行对照基线、完整 diff、责任范围及验收标准核查,运行必要测试,复用仍有效的验证证据。`permission_denials` 非零或报告包含权限拒绝时,核实缺失项并保留权限边界。第三方成功声明不等于验收通过。
|
|
77
|
+
|
|
78
|
+
向调用方返回答案或实际变更、验证结果、未完成项,并附简短执行说明,包含:
|
|
79
|
+
|
|
80
|
+
- `requested_provider`:原定 Claude、Codex,或宿主未知。
|
|
81
|
+
- `actual_executor`:实际第三方及请求模型(可得时),或 fresh sub-agent 及其 ID。
|
|
82
|
+
- `fallback_used` 与 `fallback_reason`:是否回退及具体原因;未回退时注明无。
|
|
83
|
+
- `status`:验收后为 `ok` / `completed`,仍有缺口为 `blocked`,并说明恢复所需条件。
|
|
84
|
+
|
|
85
|
+
例如:“Claude 调用因额度不足失败,已由 fresh sub-agent <ID> 完成;验证通过。”这段说明供调用方记录,运行时与回退决策已在本技能内完成。请求模型 ID 不保证服务端未切换模型。
|
|
86
|
+
|
|
87
|
+
清理本次临时任务文件;保留仍有成果待整合的 worktree。
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
2
|
+
"""第三方技能的 Claude 通道;单次调用失败后通知宿主启动 fresh sub-agent。"""
|
|
3
3
|
|
|
4
4
|
import argparse
|
|
5
5
|
import json
|
|
@@ -86,8 +86,9 @@ def ask(prompt, timeout=120, *, mode="consult", cwd=None, start_model=None, allo
|
|
|
86
86
|
attempts = []
|
|
87
87
|
cli = shutil.which("claude")
|
|
88
88
|
if not cli:
|
|
89
|
-
return {"status": "fallback_required", "attempts": [], "reason": "未找到 claude 命令"
|
|
90
|
-
|
|
89
|
+
return {"status": "fallback_required", "attempts": [], "reason": "未找到 claude 命令",
|
|
90
|
+
"next_executor": "fresh_subagent", "partial_work_possible": False}
|
|
91
|
+
models = (start_model or MODELS[0],)
|
|
91
92
|
for model in models:
|
|
92
93
|
if model not in MODELS:
|
|
93
94
|
raise ValueError("模型不在委派链中")
|
|
@@ -147,10 +148,9 @@ def ask(prompt, timeout=120, *, mode="consult", cwd=None, start_model=None, allo
|
|
|
147
148
|
else:
|
|
148
149
|
reason = f"CLI 未返回有效答案(退出码 {process.returncode})"
|
|
149
150
|
attempts.append({"requested_model": model, "reason": reason})
|
|
150
|
-
result = {"status": "fallback_required", "attempts": attempts
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
next_model=MODELS[1] if models[0] == MODELS[0] else None)
|
|
151
|
+
result = {"status": "fallback_required", "attempts": attempts,
|
|
152
|
+
"reason": attempts[-1]["reason"], "next_executor": "fresh_subagent",
|
|
153
|
+
"partial_work_possible": mode == "task"}
|
|
154
154
|
return result
|
|
155
155
|
|
|
156
156
|
|
|
@@ -176,7 +176,9 @@ def main(argv=None):
|
|
|
176
176
|
if not prompt.strip():
|
|
177
177
|
raise ValueError("问题为空")
|
|
178
178
|
except (OSError, UnicodeError, ValueError):
|
|
179
|
-
result = {"status": "fallback_required", "attempts": [],
|
|
179
|
+
result = {"status": "fallback_required", "attempts": [],
|
|
180
|
+
"reason": "问题文件不可读或为空,请宿主向 fresh sub-agent 提供原任务",
|
|
181
|
+
"next_executor": "fresh_subagent", "partial_work_possible": False}
|
|
180
182
|
else:
|
|
181
183
|
result = ask(prompt, args.timeout, mode=args.mode, cwd=args.cwd,
|
|
182
184
|
start_model=args.start_model, allow_commands=args.allow_command)
|
package/skills/{delegate-cc/scripts/test_delegate_cc.py → delegate_3th/scripts/test_delegate_3th.py}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""覆盖 Claude 单次调用、失败回退信号与任务活性。"""
|
|
2
2
|
|
|
3
3
|
import json
|
|
4
4
|
import io
|
|
@@ -10,7 +10,7 @@ import tempfile
|
|
|
10
10
|
from pathlib import Path
|
|
11
11
|
from unittest.mock import patch
|
|
12
12
|
|
|
13
|
-
import
|
|
13
|
+
import delegate_3th as ask_3th
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
def result(answer, failed=False):
|
|
@@ -24,9 +24,9 @@ class AskCCTest(unittest.TestCase):
|
|
|
24
24
|
def test_cli_entrypoints_do_not_switch_models_after_idle_threshold(self):
|
|
25
25
|
skills = Path(__file__).resolve().parents[2]
|
|
26
26
|
entries = [
|
|
27
|
-
(skills / "
|
|
28
|
-
(skills / "
|
|
29
|
-
(skills / "
|
|
27
|
+
(skills / "ask_3th/scripts/ask_3th.py", "consult"),
|
|
28
|
+
(skills / "delegate_3th/scripts/delegate_3th.py", "consult"),
|
|
29
|
+
(skills / "delegate_3th/scripts/delegate_3th.py", "task"),
|
|
30
30
|
]
|
|
31
31
|
for entry, mode in entries:
|
|
32
32
|
with self.subTest(entry=entry, mode=mode), tempfile.TemporaryDirectory() as tmp:
|
|
@@ -56,45 +56,48 @@ class AskCCTest(unittest.TestCase):
|
|
|
56
56
|
response = json.loads(completed.stdout)
|
|
57
57
|
self.assertEqual(response["status"], "review_required" if mode == "task" else "ok")
|
|
58
58
|
self.assertEqual(response["attempts"], [])
|
|
59
|
-
self.assertEqual(calls.read_text().splitlines(), [
|
|
59
|
+
self.assertEqual(calls.read_text().splitlines(), [ask_3th.MODELS[0]])
|
|
60
60
|
self.assertIn("疑似停滞", completed.stderr)
|
|
61
61
|
|
|
62
|
-
@patch.object(
|
|
62
|
+
@patch.object(ask_3th.shutil, "which", return_value="/fake/claude")
|
|
63
63
|
def test_task_permissions_and_review(self, _which):
|
|
64
|
-
with tempfile.TemporaryDirectory() as cwd, patch.object(
|
|
65
|
-
response =
|
|
64
|
+
with tempfile.TemporaryDirectory() as cwd, patch.object(ask_3th, "run_task", return_value=result("完成")) as run:
|
|
65
|
+
response = ask_3th.ask("修改代码", mode="task", cwd=cwd, allow_commands=["python3 -m unittest"])
|
|
66
66
|
command = run.call_args.args[0]
|
|
67
67
|
self.assertEqual(response["status"], "review_required")
|
|
68
68
|
self.assertEqual(command[command.index("--permission-mode") + 1], "acceptEdits")
|
|
69
69
|
self.assertIn("Bash(python3 -m unittest)", command)
|
|
70
70
|
self.assertNotIn("bypassPermissions", command)
|
|
71
71
|
|
|
72
|
-
@patch.object(
|
|
72
|
+
@patch.object(ask_3th.shutil, "which", return_value="/fake/claude")
|
|
73
73
|
def test_partial_task_is_not_blindly_retried(self, _which):
|
|
74
74
|
with tempfile.TemporaryDirectory() as cwd:
|
|
75
75
|
def partial(*args):
|
|
76
76
|
Path(cwd, "partial.txt").write_text("已完成部分")
|
|
77
77
|
raise OSError("CLI connection failed")
|
|
78
|
-
with patch.object(
|
|
79
|
-
response =
|
|
78
|
+
with patch.object(ask_3th, "run_task", side_effect=partial) as run:
|
|
79
|
+
response = ask_3th.ask("修改代码", mode="task", cwd=cwd)
|
|
80
80
|
self.assertEqual(run.call_count, 1)
|
|
81
81
|
self.assertEqual(Path(cwd, "partial.txt").read_text(), "已完成部分")
|
|
82
|
-
self.assertEqual(response["status"], "
|
|
83
|
-
self.assertEqual(response["
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
82
|
+
self.assertEqual(response["status"], "fallback_required")
|
|
83
|
+
self.assertEqual(response["next_executor"], "fresh_subagent")
|
|
84
|
+
self.assertTrue(response["partial_work_possible"])
|
|
85
|
+
self.assertNotIn("next_model", response)
|
|
86
|
+
|
|
87
|
+
@patch.object(ask_3th.shutil, "which", return_value="/fake/claude")
|
|
88
|
+
def test_explicit_model_failure_requests_fresh_subagent(self, _which):
|
|
89
|
+
with tempfile.TemporaryDirectory() as cwd, patch.object(ask_3th, "run_task", return_value=result("usage limit", True)):
|
|
90
|
+
response = ask_3th.ask("接续", mode="task", cwd=cwd, start_model="claude-opus-5")
|
|
91
|
+
self.assertEqual(response["status"], "fallback_required")
|
|
92
|
+
self.assertEqual(response["next_executor"], "fresh_subagent")
|
|
93
|
+
self.assertNotIn("next_model", response)
|
|
91
94
|
|
|
92
95
|
def test_task_requires_explicit_directory(self):
|
|
93
96
|
with self.assertRaises(ValueError):
|
|
94
|
-
|
|
97
|
+
ask_3th.ask("修改代码", mode="task")
|
|
95
98
|
|
|
96
|
-
@patch.object(
|
|
97
|
-
def
|
|
99
|
+
@patch.object(ask_3th.shutil, "which", return_value="/fake/claude")
|
|
100
|
+
def test_first_failure_requests_fallback_without_second_model(self, _which):
|
|
98
101
|
seen = []
|
|
99
102
|
|
|
100
103
|
def cli(command, *args):
|
|
@@ -106,30 +109,49 @@ class AskCCTest(unittest.TestCase):
|
|
|
106
109
|
return result("OK")
|
|
107
110
|
return result(f"There's an issue with the selected model ({model}).", True)
|
|
108
111
|
|
|
109
|
-
with patch.object(
|
|
110
|
-
response =
|
|
111
|
-
self.assertEqual(response["status"], "
|
|
112
|
-
self.assertEqual(seen, ["claude-fable-5-1"
|
|
113
|
-
self.assertEqual(response["
|
|
112
|
+
with patch.object(ask_3th, "run_task", side_effect=cli):
|
|
113
|
+
response = ask_3th.ask("仅回答 OK")
|
|
114
|
+
self.assertEqual(response["status"], "fallback_required")
|
|
115
|
+
self.assertEqual(seen, ["claude-fable-5-1"])
|
|
116
|
+
self.assertEqual(response["next_executor"], "fresh_subagent")
|
|
117
|
+
self.assertEqual(response["reason"], "额度不足或限流")
|
|
118
|
+
|
|
119
|
+
@patch.object(ask_3th.shutil, "which", return_value=None)
|
|
120
|
+
def test_missing_cli_requests_fresh_subagent(self, _which):
|
|
121
|
+
with patch.object(ask_3th, "run_task") as run:
|
|
122
|
+
response = ask_3th.ask("问题")
|
|
123
|
+
run.assert_not_called()
|
|
124
|
+
self.assertEqual(response["status"], "fallback_required")
|
|
125
|
+
self.assertEqual(response["next_executor"], "fresh_subagent")
|
|
126
|
+
self.assertFalse(response["partial_work_possible"])
|
|
127
|
+
|
|
128
|
+
@patch.object(ask_3th.shutil, "which", return_value="/fake/claude")
|
|
129
|
+
def test_invalid_result_requests_fresh_subagent_once(self, _which):
|
|
130
|
+
for output in ["not json", json.dumps({"type": "result", "subtype": "success", "result": " "})]:
|
|
131
|
+
with self.subTest(output=output), patch.object(ask_3th, "run_task", return_value=
|
|
132
|
+
subprocess.CompletedProcess([], 0, output, "")) as run:
|
|
133
|
+
response = ask_3th.ask("问题")
|
|
134
|
+
self.assertEqual(run.call_count, 1)
|
|
135
|
+
self.assertEqual(response["next_executor"], "fresh_subagent")
|
|
114
136
|
|
|
115
|
-
@patch.object(
|
|
137
|
+
@patch.object(ask_3th.shutil, "which", return_value="/fake/claude")
|
|
116
138
|
def test_unrecognized_model_is_reported(self, _which):
|
|
117
139
|
failure = result("There's an issue with the selected model (fable-5.1). It may not exist or you may not have access to it.", True)
|
|
118
|
-
with patch.object(
|
|
119
|
-
response =
|
|
140
|
+
with patch.object(ask_3th, "run_task", return_value=failure):
|
|
141
|
+
response = ask_3th.ask("问题")
|
|
120
142
|
self.assertEqual(response["status"], "fallback_required")
|
|
121
143
|
self.assertEqual(response["attempts"][0]["reason"], "模型名称无效或当前账户无权访问")
|
|
122
144
|
|
|
123
|
-
@patch.object(
|
|
145
|
+
@patch.object(ask_3th.shutil, "which", return_value="/fake/claude")
|
|
124
146
|
def test_login_error_is_distinct(self, _which):
|
|
125
|
-
with patch.object(
|
|
126
|
-
response =
|
|
147
|
+
with patch.object(ask_3th, "run_task", return_value=result("Not logged in · Please run /login", True)):
|
|
148
|
+
response = ask_3th.ask("问题")
|
|
127
149
|
self.assertEqual(response["attempts"][0]["reason"], "认证不可用")
|
|
128
150
|
|
|
129
151
|
def test_silent_process_survives_idle_warning(self):
|
|
130
152
|
command = [sys.executable, "-c", "import time; time.sleep(0.2); print('done')"]
|
|
131
|
-
with patch.object(
|
|
132
|
-
completed =
|
|
153
|
+
with patch.object(ask_3th.sys, "stderr", new_callable=io.StringIO) as log:
|
|
154
|
+
completed = ask_3th.run_task(command, "", 0.05, None)
|
|
133
155
|
self.assertEqual(completed.returncode, 0)
|
|
134
156
|
self.assertEqual(completed.stdout.strip(), "done")
|
|
135
157
|
self.assertIn("疑似停滞", log.getvalue())
|
|
@@ -137,8 +159,8 @@ class AskCCTest(unittest.TestCase):
|
|
|
137
159
|
def test_streaming_process_survives_total_duration(self):
|
|
138
160
|
command = [sys.executable, "-u", "-c",
|
|
139
161
|
"import time\nfor i in range(8):\n print(i)\n time.sleep(0.04)"]
|
|
140
|
-
with patch.object(
|
|
141
|
-
completed =
|
|
162
|
+
with patch.object(ask_3th.sys, "stderr", new_callable=io.StringIO):
|
|
163
|
+
completed = ask_3th.run_task(command, "", 0.1, None)
|
|
142
164
|
self.assertEqual(completed.returncode, 0)
|
|
143
165
|
self.assertEqual(completed.stdout.splitlines(), [str(i) for i in range(8)])
|
|
144
166
|
|
|
@@ -147,19 +169,19 @@ class AskCCTest(unittest.TestCase):
|
|
|
147
169
|
subprocess.run(["git", "init", "-q", cwd], check=True)
|
|
148
170
|
file = Path(cwd, "work.txt")
|
|
149
171
|
file.write_text("before")
|
|
150
|
-
before =
|
|
172
|
+
before = ask_3th.workspace_activity(cwd)
|
|
151
173
|
file.write_text("after!")
|
|
152
|
-
self.assertNotEqual(before,
|
|
153
|
-
before =
|
|
174
|
+
self.assertNotEqual(before, ask_3th.workspace_activity(cwd))
|
|
175
|
+
before = ask_3th.workspace_activity(cwd)
|
|
154
176
|
file.unlink()
|
|
155
|
-
self.assertNotEqual(before,
|
|
177
|
+
self.assertNotEqual(before, ask_3th.workspace_activity(cwd))
|
|
156
178
|
|
|
157
|
-
@patch.object(
|
|
179
|
+
@patch.object(ask_3th.shutil, "which", return_value="/fake/claude")
|
|
158
180
|
def test_stream_events_resolve_final_result(self, _which):
|
|
159
181
|
output = result("完成")
|
|
160
182
|
output.stdout = json.dumps({"type": "assistant", "message": "working"}) + "\n" + output.stdout
|
|
161
|
-
with patch.object(
|
|
162
|
-
response =
|
|
183
|
+
with patch.object(ask_3th, "run_task", return_value=output) as run:
|
|
184
|
+
response = ask_3th.ask("问题")
|
|
163
185
|
self.assertEqual(response["answer"], "完成")
|
|
164
186
|
self.assertIn("stream-json", run.call_args.args[0])
|
|
165
187
|
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: project-agent-standards
|
|
3
|
+
description: 审核并补齐项目面向 agent 的 GitHub 模板、开发评审规范、DX 工作流与回访 Issue 规则,将 AGENTS.md 整理为按需读取的渐进披露结构。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 项目 Agent 规范整备
|
|
7
|
+
|
|
8
|
+
对用户指定仓库执行审核并补齐缺项;未指定时使用当前仓库。只读审核请求只报告差异。默认执行本地可回退的模板和文档修改,不包含提交、推送、发布 Issue / PR、安装工具或改造构建系统。现有全局技能保持不变。
|
|
9
|
+
|
|
10
|
+
## 1. 建立项目依据
|
|
11
|
+
|
|
12
|
+
检查工作区状态,读取目标及祖先的 `AGENTS.md`。按需检查已有规范、贡献指南、GitHub 模板、技术栈清单、任务配置和 CI。优先搜索标题与职责,不能仅凭文件名判定规范缺失。
|
|
13
|
+
|
|
14
|
+
记录以下六项的现状、路径和缺口:Issue / PR 模板、agent 引用、开发评审规范、DX / Nx 工作流、回访规则、AGENTS.md 渐进披露结构。检查根及模块 agent 入口的内容分工、读取条件和引用链;祖先指令用于确定约束,不修改目标仓库之外的文件。区分已配置的命令、实际运行结果与未来建议;不读取或输出秘密值。
|
|
15
|
+
|
|
16
|
+
完成条件:每项均有存在证据或明确的缺失结论,能够识别目标模块与实际工具链。
|
|
17
|
+
|
|
18
|
+
## 2. 补齐 GitHub 模板
|
|
19
|
+
|
|
20
|
+
使用随技能携带的完整模板,无需访问原始项目:
|
|
21
|
+
|
|
22
|
+
| 资源 | 目标标准位置 |
|
|
23
|
+
| --- | --- |
|
|
24
|
+
| [Issue 模板](assets/github/ISSUE_TEMPLATE/issue.md) | `.github/ISSUE_TEMPLATE/issue.md` |
|
|
25
|
+
| [PR 模板](assets/github/pull_request_template.md) | `.github/pull_request_template.md` |
|
|
26
|
+
|
|
27
|
+
目标缺失时创建目录并直接复制。目标已有等效内容时保留;空文件或缺少模板必需结构时,以资源覆盖该目标文件。覆盖前保留目标的未提交或未跟踪原文到仓库外的临时备份,并记录路径;已提交的原文可通过 Git 恢复。用户明确要求统一为附带模板时直接覆盖。
|
|
28
|
+
|
|
29
|
+
检查根目录、`docs/` 与 `.github/` 是否有竞争的默认 PR 模板;将仍适用的独有约束合入标准模板,再清理被取代的默认副本并更新引用。保留用途不同的 Issue Forms、多模板及配置,不因其存在就删除。已有标准文件中的项目专属验收要求同样需要保留。
|
|
30
|
+
|
|
31
|
+
完成条件:两个标准位置均有可用模板,默认 PR 模板选择无冲突,独有约束和用户原文可追踪。
|
|
32
|
+
|
|
33
|
+
## 3. 补齐面向 agent 的参考文档
|
|
34
|
+
|
|
35
|
+
按缺口读取对应资源,依照源码、配置和已有决策改写。现有等效文档优先就地补齐并继续使用其路径;只有缺失时才使用表中的默认路径。
|
|
36
|
+
|
|
37
|
+
| 缺项 | 适配资源 | 默认路径 |
|
|
38
|
+
| --- | --- | --- |
|
|
39
|
+
| 开发与评审规范 | [开发规范骨架](assets/development-standards.md) | `docs/guides/development-standards.md` |
|
|
40
|
+
| DX / Nx 工作流 | [工作流骨架](assets/dx-development-workflow.md) | `docs/guides/dx-development-workflow.md` |
|
|
41
|
+
| 回访规则 | [回访规则](assets/follow-up-issues.md) | `docs/agents/follow-up-issues.md` |
|
|
42
|
+
|
|
43
|
+
文档写给执行任务的 agent:说明触发条件、具体决策、命令前置条件、失败处理与完成证据。删除骨架中的编写提示及不适用分支,替换所有 `{{...}}`。保留目标项目语言约定,无约定时使用简体中文。
|
|
44
|
+
|
|
45
|
+
开发规范应覆盖实际模块与风险;不会因使用此技能就迁移成三层架构或引入新的测试框架。将已有约束、此次建立的规则和未来建议分清;尚未接入的检查不能写成已经运行的门禁。
|
|
46
|
+
|
|
47
|
+
DX 文档必须检查实际 DX 配置、Nx 目标与 CLI 能力。已接入则记录真实命令;只接入其一则分别说明职责;均未接入也生成说明,明确“未接入”并给出现有命令,不编造 `dx` 入口。工具链接入是另一个任务。
|
|
48
|
+
|
|
49
|
+
回访规则合入现有 Issue 规范的对应章节;没有载体时才创建独立文档。沿用目标项目的本地或远程追踪方式,不引入原始项目的 `.scratch/` 默认存储决定。
|
|
50
|
+
|
|
51
|
+
完成条件:三类说明可被 agent 直接使用,命令有配置依据,待确认事实明确列出,无未替换占位符。
|
|
52
|
+
|
|
53
|
+
## 4. 检查并改造 AGENTS.md 的渐进披露结构
|
|
54
|
+
|
|
55
|
+
渐进披露按任务需要加载说明:根入口保留项目识别、全局必需约束与条件明确的文档入口;模块入口保留该目录适用的规则;详细流程、命令说明、模板字段和专题规范放在被引用文档中。判断依据是内容职责与加载方式,不以行数或是否已有链接判定。只有简短必需规则的入口无需为了拆分而创建文件。
|
|
56
|
+
|
|
57
|
+
存在下列情况时,在本次整备中直接改造:入口堆放仅特定任务需要的详细流程;所有专题文档被要求无条件全文加载;只有链接而没有读取条件;相同规范在多个入口重复维护。只读审核请求则报告问题和迁移建议。
|
|
58
|
+
|
|
59
|
+
1. 按原有规则的适用范围梳理内容,保留全局必需约束及模块覆盖关系;将条件性细节归入现有等效文档,缺少载体时再按专题创建文档,沿用项目目录约定。
|
|
60
|
+
2. 在原入口用“执行什么任务时,必须读取哪个文档”的短指令替换已迁移细节。适用时才读取的专题不使用无条件全文导入;避免入口互相引用或仅为转发再增加一层目录页。
|
|
61
|
+
3. 更新迁移内容中的相对链接和其他引用,确保目标存在且能从入口到达。保留原规则的强制程度、例外、权限边界和历史决策,不因移动位置而削弱要求。修改未提交或未跟踪原文前保存仓库外备份并记录路径。
|
|
62
|
+
4. 建立原章节到新位置的对应记录,逐项核对无遗漏后再删除重复正文。已有合适结构则就地补齐缺失的读取条件和链接,重复执行不重复拆分。
|
|
63
|
+
|
|
64
|
+
在根 `AGENTS.md` 放 GitHub 模板和回访规则的触发入口;模块独有的开发规范放在模块 `AGENTS.md`。若仓库采用其他 agent 入口,复用其引用链;缺少入口则创建根 `AGENTS.md`。参考以下文字并替换为真实的相对链接:
|
|
65
|
+
|
|
66
|
+
> 创建或更新 GitHub Issue / PR 正文时,必须读取并使用 [Issue 模板](.github/ISSUE_TEMPLATE/issue.md) / [PR 模板](.github/pull_request_template.md)。网页、CLI、API 和技能操作均适用。正文结构和填写要求以模板为准;发布前检查必填章节与占位内容。
|
|
67
|
+
|
|
68
|
+
> 开发、修复或评审代码时,按任务范围读取 [开发与评审规范](docs/guides/development-standards.md) 的相关章节。
|
|
69
|
+
|
|
70
|
+
> 初始化环境、选择启动 / 验证 / 构建命令或排查环境注入时,读取 [开发工作流](docs/guides/dx-development-workflow.md) 的相关章节。
|
|
71
|
+
|
|
72
|
+
> 创建、更新或转为回访用途的 Issue 时,读取 [回访规则](docs/agents/follow-up-issues.md)。
|
|
73
|
+
|
|
74
|
+
入口保留必要约束和读取条件。模板字段留在模板,命令细节留在工作流,回访标识留在 Issue 规范。将仓库其他位置同义重复的说明改成引用或删除;保留模块专属约束与历史决策。重复运行时复用既有入口,不追加相同规则。
|
|
75
|
+
|
|
76
|
+
完成条件:入口、模块规则与专题细节分工清楚,每个按需文档都有明确触发条件,原有有效约束完整保留,没有失效链接、循环引用或无条件加载所有专题的要求。
|
|
77
|
+
|
|
78
|
+
## 5. 验证与交付
|
|
79
|
+
|
|
80
|
+
检查差异、Markdown 链接、模板 frontmatter、占位符和竞争模板。逐项复核第 1 步的六项清单与所有新引用,确认再执行一次不会增加文件或重复条目。对照迁移记录检查规则完整性,并分别用代码修改、Issue / PR 编写和回访任务走查入口,确认能够找到对应规范,且不会要求加载无关专题。
|
|
81
|
+
|
|
82
|
+
纯文档修改按项目规则做差异与格式验证;验证命令存在可以检查配置或安全的帮助输出,不为文档审核运行发布、迁移或全仓测试。报告每项的保留 / 新建 / 更新状态、文件链接、实际验证和未确认事项,以及渐进披露检查结论与章节迁移去向;未接入 DX / Nx 要明确说明。不要将文档中列出的命令写成已经执行通过。
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
<!-- 编写提示:这是适配骨架,不是可直接复制的项目决策。用实际目录、框架和验证目标替换变量,删除不适用章节与本提示。 -->
|
|
2
|
+
# {{项目或模块}} 开发与评审规范
|
|
3
|
+
|
|
4
|
+
适用范围:{{目录与业务入口}}。
|
|
5
|
+
依据:{{已有架构决策、领域术语、工具配置的相对链接}}。
|
|
6
|
+
|
|
7
|
+
## 规范与执行
|
|
8
|
+
|
|
9
|
+
开发、修复和评审时按改动范围读取对应章节。“必须”是验收要求,“应”允许有依据的偏离,“可”是可选方案。新增规则的目标状态与现有实现分开记录;文档本身不证明实现合规。
|
|
10
|
+
|
|
11
|
+
开始实现前明确输入输出、权限、业务不变量、失败行为和验证方式。架构例外按项目既有决策机制处理,并在 PR 模板对应章节记录影响及验证。
|
|
12
|
+
|
|
13
|
+
## 模块边界与依赖
|
|
14
|
+
|
|
15
|
+
{{记录实际模块、各层职责、允许的依赖方向、入口与组装位置,以及一组目标仓库真实路径。单体、库、前端或脚本项目按自身结构填写。}}
|
|
16
|
+
|
|
17
|
+
公共接口暴露调用者需要的能力;基础设施与第三方细节留在适配边界。修改共享接口时检查实际消费方,并说明兼容方式。
|
|
18
|
+
|
|
19
|
+
## 契约、状态与错误
|
|
20
|
+
|
|
21
|
+
{{记录协议或组件接口的真源、生成文件边界、输入校验、错误码或异常约定。}}
|
|
22
|
+
|
|
23
|
+
边界明确空值、非法输入、超时、取消与重复操作的行为。状态变化通过可观察结果验收。诊断遵循项目语言及脱敏规则,避免暴露凭据和用户敏感内容。
|
|
24
|
+
|
|
25
|
+
## 数据与外部副作用
|
|
26
|
+
|
|
27
|
+
{{仅在存在持久化或远程调用时保留:事务边界、并发约束、幂等、重试、迁移兼容性、失败恢复及资源生命周期。引用实际实现约定,不默认引入事务框架或 Outbox。}}
|
|
28
|
+
|
|
29
|
+
## 界面与交互
|
|
30
|
+
|
|
31
|
+
{{仅在存在界面时保留:状态归属、加载/空/错误状态、可访问性、响应式、已有设计系统、前后端契约和关键交互验收。}}
|
|
32
|
+
|
|
33
|
+
## 安全、配置与运行
|
|
34
|
+
|
|
35
|
+
{{说明实际身份与权限边界、配置来源及优先级、秘密存储、启停与日志约定。依项目风险补充资源限制和可观测性。}}
|
|
36
|
+
|
|
37
|
+
## 验证与评审
|
|
38
|
+
|
|
39
|
+
按变更风险选择能观察行为的检查:业务逻辑、接口、持久化、交互及跨模块链路分别映射到现有测试入口。缺少自动化覆盖时记录具体缺口,不把计划中的检查当成已接入门禁。
|
|
40
|
+
|
|
41
|
+
| 变更范围 | 验收证据 | 命令依据 |
|
|
42
|
+
| --- | --- | --- |
|
|
43
|
+
| {{真实模块或变更类型}} | {{需验证的行为、失败路径}} | {{链接到工作流对应章节}} |
|
|
44
|
+
|
|
45
|
+
纯文档核对差异、格式和引用;代码改动执行覆盖本次风险的检查。相关检查已通过且输入未变化时不重复运行。按证据区分本次回归、既有失败和环境问题;验证结果统一填写 PR 模板。
|
|
46
|
+
|
|
47
|
+
## 规范维护
|
|
48
|
+
|
|
49
|
+
{{列出本项目特有的评审要点及已知未落实要求。只引用真实存在的文档;需要外部依据时核对所用框架版本,未核实的判断标为待确认。}}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<!-- 编写提示:先检查项目实际配置。未接入 DX / Nx 时保留标题但明确状态,将命令表改为现有工具入口;删除无关章节、变量和本提示。 -->
|
|
2
|
+
# DX 与 Nx 开发工作流
|
|
3
|
+
|
|
4
|
+
供 agent 在初始化环境、选择命令或排查执行问题时按需读取。
|
|
5
|
+
|
|
6
|
+
## 工具职责与真源
|
|
7
|
+
|
|
8
|
+
接入状态:{{DX 与 Nx 分别为已接入 / 未接入;缺少 CLI 与缺少仓库配置分别说明}}。
|
|
9
|
+
|
|
10
|
+
{{列出公开任务入口、内部编排工具、实际配置路径及版本依据。只有已验证使用全局 DX 时才写全局安装策略;不套用其他仓库包名、版本或目录。}}
|
|
11
|
+
|
|
12
|
+
## 环境准备
|
|
13
|
+
|
|
14
|
+
{{记录实际运行时版本来源、依赖安装命令、所需服务及其由谁管理。没有初始化入口就列现有必要步骤,不虚构 dx setup。}}
|
|
15
|
+
|
|
16
|
+
## 配置与注入
|
|
17
|
+
|
|
18
|
+
{{记录环境选择参数、配置文件加载顺序、秘密的本地存放位置、必须变量名及校验时机。说明绕过公开入口是否会丢失环境注入;不填写真实秘密。}}
|
|
19
|
+
|
|
20
|
+
## 命令选择
|
|
21
|
+
|
|
22
|
+
下表命令来自项目配置;“已配置”不表示本次已经运行通过。
|
|
23
|
+
|
|
24
|
+
| 任务 | 实际命令 | 前置条件 | 行为与副作用 |
|
|
25
|
+
| --- | --- | --- | --- |
|
|
26
|
+
| {{初始化 / 启动 / 检查 / 测试 / 构建中实际存在的任务}} | {{精确命令}} | {{所需依赖与环境}} | {{执行范围、产物、是否启动服务或修改数据}} |
|
|
27
|
+
|
|
28
|
+
{{DX 已接入时核对 CLI 支持的参数与目标映射;Nx 已接入时说明依赖顺序、缓存和 configuration。只记录存在的目标,明确附加路径或参数是否真的透传。}}
|
|
29
|
+
|
|
30
|
+
## 验证范围与失败处理
|
|
31
|
+
|
|
32
|
+
{{按模块列出行为验收入口,区分单元 / 集成 / E2E、Mock / 真实依赖。说明完整套件是否已包含子套件,避免重复执行。}}
|
|
33
|
+
|
|
34
|
+
环境或依赖缺失单列为未运行或环境失败;测试进程失败不能记为通过。失败证据包括实际命令、退出状态和关键原因。运行结果填写仓库 PR 模板。
|
|
35
|
+
|
|
36
|
+
## 生成产物与服务生命周期
|
|
37
|
+
|
|
38
|
+
{{有生成代码时:真源、生成目标、消费方依赖和是否入库。有服务时:启动/结束责任、端口来源、临时数据隔离与清理,以及是否自动迁移。无相应行为则删除本节。}}
|
|
39
|
+
|
|
40
|
+
## 发布边界
|
|
41
|
+
|
|
42
|
+
{{只列现有发布入口、目标环境和执行权限;没有入口就明确尚未配置。文档审核不执行发布或迁移。}}
|
|
43
|
+
|
|
44
|
+
## 尚未接入或待确认
|
|
45
|
+
|
|
46
|
+
{{只列具体缺项及其对 agent 的影响。未接入 DX / Nx 时给出现有替代入口,明确本次只补文档,未安装或接入工具链;无缺项时删除本节。}}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# 回访 Issue 规则
|
|
2
|
+
|
|
3
|
+
创建用于后续复查、跟进验证的 Issue,或将既有 Issue 转为该用途时:
|
|
4
|
+
|
|
5
|
+
- 标题使用 `[回访] 原标题`,并添加名称完全一致的 `回访` 标签;前缀与标签只保留一份,保留其他标签和流程状态。
|
|
6
|
+
- GitHub Issue 正文沿用仓库 Issue 模板,在现有章节内写清回访对象、触发条件或时间、可观察的验收标准;模板的正文结构不在此重复定义。
|
|
7
|
+
- 获得创建或更新 GitHub Issue 的授权后,若仓库缺少 `回访` label,随该次操作创建并应用;权限不足时报告标签未完成,不把 Issue 标记为全部处理完成。
|
|
8
|
+
- 项目已有本地 Issue 追踪时,一级标题保留此前缀,在 `Labels:` 行或既有标签字段记录 `回访`,沿用原状态机制。同步到 GitHub 时保留标识;本规则不改变项目的本地 / 远程追踪策略。
|
|
9
|
+
- 验证完成后按项目流程记录证据并关闭或更新状态;“回访”本身不表示验收通过。
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Issue
|
|
3
|
+
about: 提交功能、缺陷、重构或其他可执行事项
|
|
4
|
+
title: ""
|
|
5
|
+
labels: ""
|
|
6
|
+
assignees: ""
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 背景
|
|
10
|
+
|
|
11
|
+
<!-- 说明当前情况、问题或提出该事项的原因。 -->
|
|
12
|
+
|
|
13
|
+
## 目标
|
|
14
|
+
|
|
15
|
+
<!-- 说明完成后可观察的状态;明确不做的事单独列出。 -->
|
|
16
|
+
|
|
17
|
+
## 验收标准
|
|
18
|
+
|
|
19
|
+
<!-- 使用客观、可验证的条目;每条标准应能通过测试、命令或明确观察进行确认。 -->
|
|
20
|
+
|
|
21
|
+
- [ ]
|
|
22
|
+
|
|
23
|
+
## 关联
|
|
24
|
+
|
|
25
|
+
<!-- 可选。相关 Issue/PR 用 Refs: #<id> 列出;没有则删除本段。 -->
|
|
26
|
+
|
|
27
|
+
Refs: #
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
## 变更目的
|
|
2
|
+
|
|
3
|
+
<!-- 用 1-3 句话说明问题、预期结果和必要背景;不要复述 Issue 全文。 -->
|
|
4
|
+
|
|
5
|
+
## 主要改动
|
|
6
|
+
|
|
7
|
+
<!-- 用精简条目说明最终行为、契约或运维变化;不记录探索过程、agent 分工、复杂度门禁或完整日志。 -->
|
|
8
|
+
|
|
9
|
+
-
|
|
10
|
+
|
|
11
|
+
## 验证结果
|
|
12
|
+
|
|
13
|
+
<!-- 只记录当前 HEAD 的最低充分验证。每项写“命令或检查 — 状态 — 关键结果”;状态使用“通过 / 失败 / 未运行”。失败必须说明是否为已登记并在基线复现的既有问题。 -->
|
|
14
|
+
|
|
15
|
+
-
|
|
16
|
+
|
|
17
|
+
## 风险与后续
|
|
18
|
+
|
|
19
|
+
<!-- 统一列出未覆盖范围、已知风险、follow-up 和合并/发布后动作;每项标注“阻塞 / 非阻塞 / 发布后”。存在“阻塞”项时不得合并;没有则填写“无”。 -->
|
|
20
|
+
|
|
21
|
+
无
|
|
22
|
+
|
|
23
|
+
## 关联
|
|
24
|
+
|
|
25
|
+
<!-- 主 Issue 使用 Closes: #<issue-id>;其他关联使用 Refs: #<issue-id>。 -->
|
|
26
|
+
|
|
27
|
+
Closes: #
|
|
@@ -8,7 +8,7 @@ disable-model-invocation: true
|
|
|
8
8
|
|
|
9
9
|
统一 Codex 与 Claude Code 的 Issue → 实现 → PR → 审查修复 → 验证 → 合并交付流程。
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
本文件包含完整交付流程,第三方协作统一通过 `ask_3th` 与 `delegate_3th` 完成。依次完成下列步骤;已有成果按验收标准承接,缺失的 Issue、方案审核、审查评论或验证报告必须补齐。
|
|
12
12
|
|
|
13
13
|
## 执行边界与优先级
|
|
14
14
|
|
|
@@ -51,27 +51,37 @@ Issue/PR 正文及评论优先使用结构化工具参数;使用 CLI 时将多
|
|
|
51
51
|
|
|
52
52
|
简单任务由主线程拟定必要步骤并直接实现。复杂任务必须依次完成:
|
|
53
53
|
|
|
54
|
+
### 每次交付的第三方调用次数
|
|
55
|
+
|
|
56
|
+
同一 Issue/PR 的本次交付中,以下三个阶段分别只有一次有效调用机会,独立计数:
|
|
57
|
+
|
|
58
|
+
| 阶段 | 技能 | 有效返回后的后续工作 |
|
|
59
|
+
| --- | --- | --- |
|
|
60
|
+
| 复杂方案讨论与审核 | `ask_3th` | 主 agent 处理进一步讨论、分歧与方案修订 |
|
|
61
|
+
| 复杂修改与实现 | `delegate_3th` | 主 agent 完成补充修改、修复与验证 |
|
|
62
|
+
| 复杂 Code Review | `ask_3th` | 主 agent 处理 findings、修复及后续复审 |
|
|
63
|
+
|
|
64
|
+
调用失败不占次数,可以通过同一技能重试;重试沿用已有成果,只处理剩余工作。按技能的最终返回计数,内部运行时选择与回退仍由技能负责。获得实质意见、审查报告或可供复核的实施结果即占用一次机会;存在分歧、findings 或验收需要补修,不视为调用失败。失败且仍无有效结果时保留该阶段待完成状态,有明确阻塞则先处理阻塞,避免无进展地重复调用。
|
|
65
|
+
|
|
66
|
+
在交付记录中维护三个阶段的有效调用状态和结果摘要。后续讨论、修复循环、推送新提交或恢复同一交付不会重置次数;已有对应阶段的有效结果时直接承接。独立 follow-up Issue 的交付单独计数。主 agent 接手后仍须完成验收、评论与验证,调用次数限制不缩减这些要求。
|
|
67
|
+
|
|
68
|
+
### 方案步骤
|
|
69
|
+
|
|
54
70
|
1. 主线程先提出方案,包含现状、目标、拟改文件/模块、接口与数据影响、风险、验收和测试计划。
|
|
55
|
-
2.
|
|
56
|
-
3.
|
|
71
|
+
2. 调用 `ask_3th` 审核方案,提供需求、规划约束及相关源码;仅咨询,不授予写权限。
|
|
72
|
+
3. 主线程核验返回意见,修订方案,记录采纳项、未采纳理由及最终方案。有效咨询后的关键分歧由主 agent 查证并解决,方案确定后才进入实施。
|
|
57
73
|
|
|
58
|
-
如果接手时复杂改动已存在,先根据现有 diff
|
|
74
|
+
如果接手时复杂改动已存在,先根据现有 diff 整理方案,按阶段记录补齐尚未取得有效结果的咨询或实施委托;已用过对应机会的阶段由主 agent 核查和修正,无需删除成果重做。
|
|
59
75
|
|
|
60
76
|
## 4. 实施与主线程复核
|
|
61
77
|
|
|
62
|
-
|
|
78
|
+
复杂任务尚未取得有效实施结果时调用 `delegate_3th`,有效返回后的补充修改与修复由主 agent 直接完成;简单任务主线程直接实施。交接包含最终方案、Issue、工作目录、责任文件、项目约束、已完成成果、验收标准及实际验证命令。主线程负责方案定稿、协调、验收及本次 Git/GitHub 交付,实施者只修改分配文件。
|
|
63
79
|
|
|
64
80
|
咨询与审查只读,实施才授予必要写权限。不同执行者避免同时修改同一范围,可在不重叠文件上继续工作;需要隔离时使用独立 worktree。任务书必须带上相关流程和项目规则,不能假定执行通道能加载技能。
|
|
65
81
|
|
|
66
82
|
第三方完成后,主线程核对完整 diff、责任范围和验收标准,检查遗漏、回归、越界改动与测试证据,处理发现的问题。第三方返回成功不等于主线程已验收,也不替代后续 PR Code Review。
|
|
67
83
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
### 委派活性与接管
|
|
71
|
-
|
|
72
|
-
保存本次任务 ID、工作目录、输出来源和责任文件基线,持续观察同一任务。有效日志、工具进展或责任文件变化可以证明活动;只读任务不要求文件修改。
|
|
73
|
-
|
|
74
|
-
单次等待超时或静默告警只触发诊断,检查原会话、子命令、权限等待与错误;重复空心跳不代表进展。确认失败或无法推进后优先恢复;接管前确认原执行者及其写进程已停止,再核对现有成果,仅完成剩余工作。遵守用户取消要求,不盲目重放任务或绕过权限拒绝。
|
|
84
|
+
复杂任务的方案审核、实施与 Code Review 各取得一次对应技能的有效结果,后续工作由主 agent 直接完成。本流程按返回的答案、改动与验证证据验收,将技能附带的执行说明记录到 Issue/PR;未完成项按实际缺口处理。
|
|
75
85
|
|
|
76
86
|
## 5. 提交代码并创建或更新 PR
|
|
77
87
|
|
|
@@ -83,13 +93,13 @@ Issue/PR 正文及评论优先使用结构化工具参数;使用 CLI 时将多
|
|
|
83
93
|
|
|
84
94
|
## 6. Code Review、评论与修复循环
|
|
85
95
|
|
|
86
|
-
按最新复杂度选择审查方式:简单任务由主线程直接 Code Review
|
|
96
|
+
按最新复杂度选择审查方式:简单任务由主线程直接 Code Review;复杂任务在尚未取得本次交付的有效 Code Review 时调用 `ask_3th`,要求独立审查。有效返回后,主线程核验关键证据并负责后续复审,如实标注主 agent 审查。
|
|
87
97
|
|
|
88
98
|
首次审查覆盖本次完整 PR diff 及必要上下文。每轮完成后都向 PR 发布 Code Review 结果评论,包括审查方式、实际审查者、被审查 head SHA、覆盖范围、发现及结论;无发现也要留下记录。每条发现给出严重程度、文件位置、触发条件、影响与修复建议。
|
|
89
99
|
|
|
90
100
|
存在有效问题时完成修复并推送,在 PR 发布修复报告评论:逐项关联发现、说明修复内容、提交与验证结果;不采纳的意见写明证据和理由。阻塞验收或影响正确性、安全的未解决问题不能转成 follow-up 后视为通过。
|
|
91
101
|
|
|
92
|
-
修复后判断是否需要再次 Code Review
|
|
102
|
+
修复后判断是否需要再次 Code Review:修改行为、接口、数据/并发逻辑,修复重大问题,或引入新风险时必须由主 agent 复审。复审覆盖修复增量与受影响调用方,范围扩大时重新覆盖完整 diff,并发布新一轮审查评论。纯文字或不改变行为的修正可核对后不再审查,但在修复报告中写明理由。主 agent 持续修复和复审直至阻塞性发现解决,不再增加第三方有效调用次数。
|
|
93
103
|
|
|
94
104
|
## 7. 最终运行、编译与测试验证
|
|
95
105
|
|
|
@@ -122,13 +132,15 @@ Issue/PR 正文及评论优先使用结构化工具参数;使用 CLI 时将多
|
|
|
122
132
|
|
|
123
133
|
全过程发现新的范围外问题时,搜索去重后直接创建或补充 follow-up Issue,按项目模板与规划记录复现/证据、影响、目标、验收标准、来源 Issue/PR 和依赖。当前验收必须解决的问题留在本次修复循环,不能通过拆 Issue 绕过合并门禁。
|
|
124
134
|
|
|
135
|
+
回访性质的 follow-up(例如发布后效果检查、观察期结束后的验证或问题修复后的跟踪确认)必须添加回访标签。优先使用项目已有的回访标签;没有对应标签时创建 `回访` 并添加。复用已有 Issue 时也要补齐标签,保留其他标签,并读回确认。正文写明回访时间或触发条件、检查对象和完成标准;尚未到回访时机的任务按等待项处理。
|
|
136
|
+
|
|
125
137
|
| Follow-up 状态 | 处理 |
|
|
126
138
|
| --- | --- |
|
|
127
|
-
| 无阻塞,代码与所需资源均可用 | 直接创建独立 worktree
|
|
139
|
+
| 无阻塞,代码与所需资源均可用 | 直接创建独立 worktree,调用 `delegate_3th` 委托完整交付,要求执行 `ship-issue-pr` 同一套流程 |
|
|
128
140
|
| 依赖当前 PR、其他任务或尚未满足的条件 | 在 Issue 按项目支持的状态/标签标记等待,写明阻塞对象与解除条件;条件满足后再派发 |
|
|
129
141
|
| 需要额外外部资源、人工决策、账号或权限 | 只创建 Issue 并列出需要谁提供什么,不派发执行者 |
|
|
130
142
|
|
|
131
|
-
主线程维护后续队列,记录 Issue、状态、依赖、worktree
|
|
143
|
+
主线程维护后续队列,记录 Issue、状态、依赖、worktree、委托标识与交付进度,避免重复派发。运行中的依赖完成、当前 PR 合并或收到条件变更时重查等待项;如需跨会话等待,使用宿主可用的持久任务/提醒机制,记录唤醒条件与检查方式。宿主不支持持久等待时,将等待项与恢复条件明确交付,不能声称会自动唤醒。
|
|
132
144
|
|
|
133
145
|
子任务采用各自责任范围与正确基线,交接 Issue、验收、项目规则和完整交付终点。依赖父 PR 时等合并后从最新基线派发。子任务发现新问题仍创建 follow-up Issue,交回主线程统一去重与调度,避免重复或递归派发。外部资源后来齐备时,重新判断阻塞并进入可派发队列。
|
|
134
146
|
|
|
@@ -136,76 +148,17 @@ Issue/PR 正文及评论优先使用结构化工具参数;使用 CLI 时将多
|
|
|
136
148
|
|
|
137
149
|
最终报告实际终点、本次改动、复杂度、第三方执行情况、审查/修复/验证评论链接、Issue/PR 状态,以及 follow-up 的已派发、等待和外部资源清单。已设置自动合并与已合并分别陈述;有阻塞时明确停在哪一步、缺什么以及恢复条件。
|
|
138
150
|
|
|
139
|
-
##
|
|
140
|
-
|
|
141
|
-
依据当前会话和可用工具确定宿主,不按模型名称或“本机同时装了哪些 CLI”判断,无需用户选择运行时。
|
|
151
|
+
## 第三方协作接口
|
|
142
152
|
|
|
143
|
-
|
|
|
153
|
+
| 工作 | 调用技能 |
|
|
144
154
|
| --- | --- |
|
|
145
|
-
|
|
|
146
|
-
|
|
|
147
|
-
| 其他或外部工具不可用 | 简单任务由当前执行者完成;复杂任务记录第三方通道阻塞,按第 4 步处理 |
|
|
148
|
-
|
|
149
|
-
简单任务直接推进。复杂任务必须使用当前宿主对应的第三方通道:Codex 调用 Claude Code,Claude Code 调用 Codex。普通同宿主 sub-agent 可承接 follow-up,但不替代复杂任务的第三方步骤。外部执行者接手的是分配范围,完整交付与事实核验仍由主线程负责。
|
|
150
|
-
|
|
151
|
-
## Codex 运行时
|
|
152
|
-
|
|
153
|
-
以下工具仅适用于 Codex 宿主确实需要 Claude 协作或已授权的后续委派时;交付范围、权限、验证复用与完成条件遵循共享流程。
|
|
154
|
-
|
|
155
|
-
### Claude 路由
|
|
156
|
-
|
|
157
|
-
| 工作 | 技能 |
|
|
158
|
-
| --- | --- |
|
|
159
|
-
| 方案咨询、普通审查、对抗审查 | [ask_cc](../ask_cc/SKILL.md) |
|
|
160
|
-
| 已明确范围的实现与修复 | [delegate-cc](../delegate-cc/SKILL.md) 的 `task` 模式 |
|
|
161
|
-
|
|
162
|
-
用户显式调用统一入口后,可在其任务范围内调用这些依赖。只读取当前模式的必要说明。CLI 参数、模型顺序、认证、权限、状态解析和接续规则由依赖技能维护,不在这里复制。
|
|
163
|
-
|
|
164
|
-
`ask_cc` 的咨询模式无工具权限。交接提供问题、相关源码与 diff、路径和必要验证结果;首次完整审查覆盖本次 PR diff,后续只补增量及其影响,不要求咨询方自行读仓库。证据不足时主进程补充材料。
|
|
165
|
-
|
|
166
|
-
独立审查不复用实现或修复会话;主进程自审不得冒充独立审查。报告 findings 的位置、条件、影响与建议,主进程核验关键证据。
|
|
167
|
-
|
|
168
|
-
执行任务提供工作目录、可修改文件或模块、项目指令与实际验收命令。明确存在其他协作者,只负责分配范围,保留他人修改。需要运行验证时按依赖技能设置具体允许命令。
|
|
169
|
-
|
|
170
|
-
### 等待、验收与后续任务
|
|
171
|
-
|
|
172
|
-
保存会话 ID,读取同一任务的流式结果;静默或宿主单次等待超时先排查,接管前确保原写进程停止。依赖缺失或确实无法运行时按第 4 步记录阻塞与已完成成果,不能把降级接手计为第三方完成。
|
|
173
|
-
|
|
174
|
-
可核实的验证结果按共享流程复用,不因来自其他执行者而全部重跑。
|
|
175
|
-
|
|
176
|
-
对第 9 步已满足派发条件的 follow-up,使用 `spawn_agent` 的可用角色,prompt 指定独立 worktree、Issue、目标、交付终点和责任文件,并要求调用 `ship-issue-pr`。子任务发现新问题创建或复用 Issue,交回主线程统一调度。
|
|
177
|
-
|
|
178
|
-
## Claude Code 运行时
|
|
179
|
-
|
|
180
|
-
以下工具仅适用于 Claude Code 宿主确实需要 Codex 协作或已授权的后续委派时;交付范围、权限、验证复用与完成条件遵循共享流程。
|
|
181
|
-
|
|
182
|
-
### Codex 通道
|
|
183
|
-
|
|
184
|
-
先使用当前会话已暴露的插件能力。已安装对应 Codex 插件时,可用:
|
|
185
|
-
|
|
186
|
-
- 方案咨询、实现或定制审查:`Agent(subagent_type: "codex:codex-rescue")`,在任务书中明确只读或可写责任范围。
|
|
187
|
-
- 普通审查:Codex companion 的 `review`。
|
|
188
|
-
- 需要挑战方案假设时:companion 的 `adversarial-review`。
|
|
189
|
-
|
|
190
|
-
通道不可用时按第 4 步记录复杂任务的阻塞,并继续可独立完成的准备。
|
|
191
|
-
|
|
192
|
-
### companion 与结果
|
|
193
|
-
|
|
194
|
-
使用插件提供的实际路径。需要定位时,仅检查当前 Claude 配置目录内对应的 marketplace/cache 路径;常见默认位置是 `~/.claude/plugins/marketplaces/openai-codex/plugins/codex` 或 `~/.claude/plugins/cache/openai-codex/codex/<version>`。以实际安装版本与 `scripts/codex-companion.mjs --help` 核实参数,不硬编码某个缓存版本。
|
|
195
|
-
|
|
196
|
-
确认后通过宿主异步工具运行,例如:
|
|
197
|
-
```bash
|
|
198
|
-
node "<plugin-root>/scripts/codex-companion.mjs" review --wait --base "<actual-base>"
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
保存本次返回的 job/agent ID、worktree 和输出位置,持续观察同一任务。返回报告仍需核对 diff、验收范围与验证证据。
|
|
202
|
-
|
|
203
|
-
### 责任与验证
|
|
155
|
+
| 方案咨询、Code Review、对抗审查 | [ask_3th](../ask_3th/SKILL.md) |
|
|
156
|
+
| 已明确范围的实现、修复或独立后续任务 | [delegate_3th](../delegate_3th/SKILL.md) 的 `task` 模式 |
|
|
204
157
|
|
|
205
|
-
|
|
158
|
+
用户显式调用本流程后,可在原任务范围与已有授权内调用上述依赖。运行时、模型、失败回退和执行者调度全部由依赖技能内部处理。本流程只提交任务、等待最终结果、验收,并将返回的执行说明附在报告中。
|
|
206
159
|
|
|
207
|
-
|
|
160
|
+
咨询提供问题、相关源码与 diff、路径和必要验证结果,标明只读及独立审查要求;首次审查覆盖本次完整 PR diff,复审补充增量和影响。证据不足时补充材料。
|
|
208
161
|
|
|
209
|
-
|
|
162
|
+
执行提供工作目录、责任文件、项目规则、已有成果、验收标准及实际验证命令。本次 PR 的实现者只负责分配范围,Git/GitHub 交付仍由主线程完成;独立 follow-up 的委托则明确授权完整交付,要求执行 `ship-issue-pr`,新发现的后续问题交回主线程统一调度。
|
|
210
163
|
|
|
211
|
-
|
|
164
|
+
保留委托标识并等待同一调用完成。收到结果后核对事实与验证证据,复用仍有效的验证;执行说明用于如实记录,不根据其内部通道或回退情况另设验收门槛。
|
package/skills/ask_cc/SKILL.md
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: ask_cc
|
|
3
|
-
description: 仅在显式调用 ask_cc 时使用:咨询 Claude Code 获取第二意见。
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# ask_cc
|
|
7
|
-
|
|
8
|
-
## 执行边界与优先级
|
|
9
|
-
|
|
10
|
-
在宿主系统与开发者指令约束内,冲突时依次采用:当前任务的具体要求与已有授权 > 目标项目适用的 AGENTS.md > 本技能及其引用的通用流程。
|
|
11
|
-
只读检索、本地草稿、可回滚编辑和常规测试可自主推断并继续;从相关文件和直接依赖开始,仅在证据不足或影响跨模块时扩大范围,复用仍有效的验证。
|
|
12
|
-
仅在不可逆或难以回滚的修改缺少具体授权时,先完成预览、草稿与验证,再说明对象和影响并等待确认;会话中已有授权继续有效。缺少事实时先查证、标注假设并推进独立工作,确实无法确定操作目标时才询问。对外发送消息须有明确授权。
|
|
13
|
-
|
|
14
|
-
使用 [delegate-cc](../delegate-cc/SKILL.md) 的咨询流程获取答案或第二意见,默认不授予工具权限。
|
|
15
|
-
|
|
16
|
-
已显式调用的 `ship-issue-pr` 需要咨询时可进入本技能,沿用原任务范围与授权。
|
|
17
|
-
|
|
18
|
-
调用前读取该技能的咨询调用与结果处理部分,按需查看诊断和接续规则。咨询没有文件修改是正常现象,以本次会话的流式输出和进程状态辅助判断;静默只触发排查,不能仅因尚无答案就停止或换模型。
|
|
19
|
-
|
|
20
|
-
若用户明确要求修改代码或执行开发任务,转入该技能的 `task` 模式,按任务范围完成实现和验收。
|
|
21
|
-
|
|
22
|
-
旧命令 `scripts/ask_cc.py --prompt-file /绝对路径/问题.txt` 继续可用,仅运行咨询模式;模型顺序和降级逻辑复用 `delegate-cc`。
|
|
23
|
-
|
|
24
|
-
旧入口的 `--timeout` 同样表示无活动告警阈值(默认 120 秒),不是答复截止时间。通过宿主异步工具保留原会话并持续取结果;只有原调用已退出且结果无效或失败时,脚本才尝试下一个模型。
|
|
25
|
-
|
|
26
|
-
`dx initial` 会同时安装这两个技能。使用当前 `SKILL.md` 所在目录下的脚本;默认安装后的调用方式:
|
|
27
|
-
|
|
28
|
-
```bash
|
|
29
|
-
python3 "$HOME/.agents/skills/ask_cc/scripts/ask_cc.py" --prompt-file /绝对路径/问题.txt
|
|
30
|
-
```
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: delegate-cc
|
|
3
|
-
description: 仅在显式调用 delegate-cc 时使用:委派 Claude Code 执行开发任务或咨询。
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# delegate-cc
|
|
7
|
-
|
|
8
|
-
## 执行边界与优先级
|
|
9
|
-
|
|
10
|
-
在宿主系统与开发者指令约束内,冲突时依次采用:当前任务的具体要求与已有授权 > 目标项目适用的 AGENTS.md > 本技能及其引用的通用流程。
|
|
11
|
-
只读检索、本地草稿、可回滚编辑和常规测试可自主推断并继续;从相关文件和直接依赖开始,仅在证据不足或影响跨模块时扩大范围,复用仍有效的验证。
|
|
12
|
-
仅在不可逆或难以回滚的修改缺少具体授权时,先完成预览、草稿与验证,再说明对象和影响并等待确认;会话中已有授权继续有效。缺少事实时先查证、标注假设并推进独立工作,确实无法确定操作目标时才询问。对外发送消息须有明确授权。
|
|
13
|
-
|
|
14
|
-
把 Claude Code 当作协作者。模型顺序固定为 Fable 5.1(`claude-fable-5-1`)→ Opus 5(`claude-opus-5`)→ 当前 sub-agent。保留本机现有认证。
|
|
15
|
-
|
|
16
|
-
已显式调用的 `ask_cc` 或 `ship-issue-pr` 需要委派时可进入本技能,沿用原任务范围与授权。
|
|
17
|
-
|
|
18
|
-
## 1. 准备交接
|
|
19
|
-
|
|
20
|
-
- **咨询 `consult`**:用户需要答案、决策建议或评审意见。提供问题、相关代码或事实、约束;CLI 无工具权限,只返回建议。
|
|
21
|
-
- **执行 `task`**:用户要求实现、修复或把开发任务交给 CC。任务书必须包含工作目录、目标、可修改文件或模块、适用的项目指令、验收标准和仓库实际验证命令。明确告知 CC 还有其他协作者,保留他人的改动,只负责分配范围。
|
|
22
|
-
|
|
23
|
-
执行前检查 `git status --short` 和任务涉及文件的 diff,记录这些文件的初始状态及相关未跟踪文件。分配互不重叠的文件;需要并发改同一文件时,先拆分责任或使用独立 worktree,指定由谁整合。worktree 不会自动携带未提交改动,必须提供任务所需的当前版本。CC 执行期间,主 agent 不同时修改其负责的文件。
|
|
24
|
-
|
|
25
|
-
将任务书写入临时 UTF-8 文件,只传必要上下文,排除凭据。完成条件:CC 无需当前对话即可理解目标、权限范围与完成标准。
|
|
26
|
-
|
|
27
|
-
## 2. 调用 CLI
|
|
28
|
-
|
|
29
|
-
需要本机提供 `python3` 和已完成认证的 `claude` CLI;`dx initial` 只同步技能文件,不安装运行时或配置认证。
|
|
30
|
-
|
|
31
|
-
运行当前 `SKILL.md` 所在目录下的 `scripts/delegate_cc.py`。以下路径适用于 `dx initial` 的默认安装位置;通过其他方式安装时使用实际技能目录:
|
|
32
|
-
|
|
33
|
-
```bash
|
|
34
|
-
# 咨询:默认模式,无活动告警阈值默认 120 秒。
|
|
35
|
-
python3 "$HOME/.agents/skills/delegate-cc/scripts/delegate_cc.py" --prompt-file /绝对路径/问题.txt
|
|
36
|
-
|
|
37
|
-
# 执行:必须指定工作目录,无活动告警阈值默认 900 秒。
|
|
38
|
-
python3 "$HOME/.agents/skills/delegate-cc/scripts/delegate_cc.py" --mode task --cwd /绝对路径/工作区 --prompt-file /绝对路径/任务.txt
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
需要 CC 自行运行验证命令时,按本次授权追加 `--allow-command '仓库实际验证命令'`,可重复传入。使用具体命令而非开放全部 Bash;根据命令和已知脚本判断副作用,仅对未知或可能破坏数据的脚本进一步检查。现有 Claude Code 权限规则仍生效,`--allow-command` 只是增加允许规则,不是独立沙箱。文件责任范围通过任务书和验收控制,需要隔离时使用 worktree 或已有沙箱。
|
|
42
|
-
|
|
43
|
-
执行模式保留默认编码系统提示,开放 `Read,Glob,Grep,Edit,Write,Bash`,使用 `acceptEdits`,不能获批的工具请求自动拒绝。两种模式都关闭 hooks、MCP 和技能,避免额外任务链;主 agent 应把所需项目规则及技能要求写入任务书。本技能不使用 `bypassPermissions`,也不扩大任务至提交、推送、部署或对外发送消息。
|
|
44
|
-
|
|
45
|
-
通过工具异步运行,至少每 60 秒向用户汇报进度,保留会话 ID。脚本读取流式输出,并比较工作目录中文件的大小和纳秒级修改/变更时间,能识别同一文件持续编辑;stderr 输出 PID、输出字节数、静默时长及观测可用性,不转发原始敏感日志。任务退出后 stdout 仍返回单个 JSON 结果。
|
|
46
|
-
|
|
47
|
-
`--timeout` 现表示无活动告警阈值,保留参数名和默认秒数;原先依赖它限制总运行时间的调用方应迁移为活性监控。达到阈值仅提示疑似停滞,脚本继续运行,不自动杀进程或换模型。输出或文件变化会重置静默计时;文件观测只覆盖 Git 跟踪及未忽略的新文件,忽略目录中的测试产物需由主进程另查。观测不可用不表示无活动,日志字节增长也需排除重复错误和空心跳。
|
|
48
|
-
|
|
49
|
-
静默告警后主进程检查原会话、日志和子命令,区分推理/测试、权限等待与实际故障;有进展则继续,无进展但证据不足则报告状态并保持任务。诊断证实无法推进时先尝试恢复原任务,必要时显式中断脚本并确认任务进程组已停止,再按下一节接续。宿主单次等待超时只继续读取同一会话,不设置固定总时长的自动终止器。完成条件:获得 JSON 结果或明确的执行失败,旧进程已结束。
|
|
50
|
-
|
|
51
|
-
## 3. 验收或接续
|
|
52
|
-
|
|
53
|
-
- `ok`:咨询获得答案;检查是否回应原问题,不能把空泛回复当作完成。
|
|
54
|
-
- `review_required`:执行已返回报告,尚待主 agent 验收。对照初始状态检查 diff、新文件及责任范围,运行必要的格式化、检查和测试。发现越界修改时先核对归属,只修正本次 CC 引入的变化。`permission_denials` 非零时核实未执行工作,使用已获授权的宿主工具完成,或准确报告实际权限阻塞。
|
|
55
|
-
- `continuation_required`:任务可能已部分执行。先检查现有 diff、测试状态及外部副作用;更新任务书为“保留已完成部分,仅完成剩余工作”。若 `next_model` 有值,以 `--start-model` 传入该值接续;每个模型最多尝试一次。禁止将同一任务从头盲目重放。
|
|
56
|
-
- `fallback_required`、第二模型也失败或 CLI 无法运行:当前执行者已经是 sub-agent 时直接接手;主 agent 则委派一个继承当前模型的 sub-agent,环境不支持委派时自己接手。提供原任务、已完成改动和剩余工作,明确跳过本技能及 CLI,避免递归。权限拒绝不能靠切换模型绕过。
|
|
57
|
-
|
|
58
|
-
咨询模式只有在原调用已退出且失败或结果无效后,脚本才尝试下一个模型;执行模式每次只运行一个模型,由主 agent 检查现场后接续。尚未返回、静默告警和宿主等待超时均不触发降级。认证、额度和模型不可用也不等于任务完成。
|
|
59
|
-
|
|
60
|
-
完成条件:咨询得到实质答案,或执行任务的代码和验证满足验收标准;仍有缺口时明确列出,而非仅转述 CC 的成功声明。
|
|
61
|
-
|
|
62
|
-
## 4. 交付
|
|
63
|
-
|
|
64
|
-
用简体中文说明答案或实际改动、验证结果、未完成项,简短注明使用的模型及降级情况。`requested_model` 是请求 ID,不保证服务端未自动切换模型。清理本次临时任务文件;保留仍有成果待整合的 worktree。
|
|
65
|
-
|
|
66
|
-
参数或模型出错时核对本机 `claude --help`、[CLI 参考](https://code.claude.com/docs/en/cli-reference)和[模型 ID](https://platform.claude.com/docs/en/models/overview)。用 `claude auth status` 区分认证状态,`unrecognized_model` 不表示未登录。
|
|
File without changes
|
|
File without changes
|
/package/skills/{delegate-cc → delegate_3th}/scripts/__pycache__/delegate_cc.cpython-314.pyc
RENAMED
|
File without changes
|
/package/skills/{delegate-cc → delegate_3th}/scripts/__pycache__/test_delegate_cc.cpython-314.pyc
RENAMED
|
File without changes
|