agentflowctl 0.4.0 → 0.6.0
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 +41 -27
- package/dist/agentConfig.js +4 -4
- package/dist/arbitration.js +12 -0
- package/dist/cli.js +17 -17
- package/dist/config.js +0 -2
- package/dist/engine.js +148 -36
- package/dist/handoff.js +109 -0
- package/dist/paths.js +1 -0
- package/dist/roles.js +70 -39
- package/dist/runner.js +2 -1
- package/dist/schemas.js +58 -3
- package/dist/setup.js +2 -2
- package/examples/flow.config.json +1 -0
- package/package.json +1 -1
- package/prompts/fix.md +11 -0
- package/prompts/implement-code.md +11 -0
- package/prompts/implement-tests.md +11 -0
- package/prompts/plan-arbiter.md +13 -1
- package/prompts/plan-fix.md +11 -0
- package/prompts/plan-review.md +12 -1
- package/prompts/plan.md +11 -0
- package/prompts/review.md +12 -1
- package/prompts/spec.md +11 -0
package/dist/roles.js
CHANGED
|
@@ -2,78 +2,109 @@
|
|
|
2
2
|
* 決定每個步驟由哪個 agent 執行。
|
|
3
3
|
*
|
|
4
4
|
* 規則只有三條:
|
|
5
|
-
* 1. 審查者不能是最後寫程式的 agent
|
|
5
|
+
* 1. 審查者不能是最後寫程式的 agent,多位審查者彼此不重複。
|
|
6
6
|
* 2. 開啟 tddSplit 時,同一個任務的測試與實作由不同 agent 負責。
|
|
7
|
-
* 3.
|
|
7
|
+
* 3. 人選隨機決定,不依 cycle 的順序。cycle 只代表有哪些 agent 參與。
|
|
8
|
+
*
|
|
9
|
+
* 隨機以 seed(run id 加上步驟與輪次)決定:同一個 run 的同一步驟重算時會得到同樣的人,
|
|
10
|
+
* 所以 resume、或同一步驟在不同地方重算時結果一致。
|
|
8
11
|
*/
|
|
9
|
-
/**
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
if (!exclude.includes(candidate))
|
|
16
|
-
return candidate;
|
|
12
|
+
/** FNV-1a 雜湊:把 seed 字串轉成 32 位元整數 */
|
|
13
|
+
function hash(seed) {
|
|
14
|
+
let h = 0x811c9dc5;
|
|
15
|
+
for (let i = 0; i < seed.length; i++) {
|
|
16
|
+
h ^= seed.charCodeAt(i);
|
|
17
|
+
h = Math.imul(h, 0x01000193);
|
|
17
18
|
}
|
|
18
|
-
return
|
|
19
|
+
return h >>> 0;
|
|
19
20
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
/** mulberry32:由 seed 決定的亂數產生器 */
|
|
22
|
+
function rng(seed) {
|
|
23
|
+
let a = hash(seed);
|
|
24
|
+
return () => {
|
|
25
|
+
a = (a + 0x6d2b79f5) >>> 0;
|
|
26
|
+
let t = a;
|
|
27
|
+
t = Math.imul(t ^ (t >>> 15), t | 1);
|
|
28
|
+
t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
|
|
29
|
+
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
|
30
|
+
};
|
|
26
31
|
}
|
|
27
|
-
/**
|
|
28
|
-
export function
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
for (let i =
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
break;
|
|
35
|
-
picked.push(next);
|
|
36
|
-
cursor = next;
|
|
32
|
+
/** 由 seed 決定的洗牌,不改動原陣列 */
|
|
33
|
+
export function shuffled(items, seed) {
|
|
34
|
+
const out = [...items];
|
|
35
|
+
const rand = rng(seed);
|
|
36
|
+
for (let i = out.length - 1; i > 0; i--) {
|
|
37
|
+
const j = Math.floor(rand() * (i + 1));
|
|
38
|
+
[out[i], out[j]] = [out[j], out[i]];
|
|
37
39
|
}
|
|
38
|
-
return
|
|
40
|
+
return out;
|
|
41
|
+
}
|
|
42
|
+
/** 隨機挑一位不在 exclude 裡的 agent;全部被排除時退回任一位(單一 agent 也能運作) */
|
|
43
|
+
export function pick(cycle, seed, exclude = []) {
|
|
44
|
+
const order = shuffled(cycle, seed);
|
|
45
|
+
return order.find((c) => !exclude.includes(c)) ?? order[0];
|
|
46
|
+
}
|
|
47
|
+
/** 規格與計畫由同一位撰寫,計畫審查才能同時避開兩者的作者 */
|
|
48
|
+
export const specAgent = (cycle, seed) => pick(cycle, `${seed}:author`);
|
|
49
|
+
export const planAgent = specAgent;
|
|
50
|
+
/**
|
|
51
|
+
* 每 cycle.length 個任務為一輪,每輪洗一次牌,所以每家輪完一次才會再輪到;
|
|
52
|
+
* 換輪時若新一輪第一位和上一輪最後一位相同,就把它往後移,避免同一家連續撰寫測試。
|
|
53
|
+
*/
|
|
54
|
+
function taskBag(cycle, seed, bag) {
|
|
55
|
+
const order = shuffled(cycle, `${seed}:tasks:${bag}`);
|
|
56
|
+
if (bag === 0 || order.length < 2)
|
|
57
|
+
return order;
|
|
58
|
+
const prevLast = taskBag(cycle, seed, bag - 1).at(-1);
|
|
59
|
+
return order[0] === prevLast ? [...order.slice(1), order[0]] : order;
|
|
60
|
+
}
|
|
61
|
+
/** 第 i 個任務的測試作者從洗好的牌依序取;實作者隨機挑一位測試作者以外的 agent */
|
|
62
|
+
export function taskAgents(cycle, taskIndex, tddSplit, seed) {
|
|
63
|
+
const n = cycle.length;
|
|
64
|
+
const tests = taskBag(cycle, seed, Math.floor(taskIndex / n))[taskIndex % n];
|
|
65
|
+
return { tests, code: tddSplit ? pick(cycle, `${seed}:code:${taskIndex}`, [tests]) : tests };
|
|
66
|
+
}
|
|
67
|
+
/** 隨機挑出 quorum 位彼此不重複、而且不是作者的 reviewer */
|
|
68
|
+
export function reviewers(cycle, lastWriter, quorum, seed) {
|
|
69
|
+
const picked = shuffled(cycle.filter((c) => c !== lastWriter), seed).slice(0, quorum);
|
|
70
|
+
return picked.length ? picked : [lastWriter ?? cycle[0]];
|
|
39
71
|
}
|
|
40
72
|
/**
|
|
41
73
|
* 誰來修正:
|
|
42
74
|
* - verify 失敗(型別、lint、建置這類機械性錯誤):交給最後寫程式的 agent
|
|
43
|
-
* - review 要求修改:ring
|
|
75
|
+
* - review 要求修改:ring 策略隨機挑一位 reviewer 以外的 agent;author 策略交回作者
|
|
44
76
|
*/
|
|
45
77
|
export function fixAgent(cycle, opts) {
|
|
46
78
|
if (opts.source === "verify" || opts.strategy === "author")
|
|
47
79
|
return opts.lastWriter ?? cycle[0];
|
|
48
|
-
return
|
|
80
|
+
return pick(cycle, opts.seed, opts.lastReviewer ? [opts.lastReviewer] : []);
|
|
49
81
|
}
|
|
50
|
-
/** 計畫修正者:ring
|
|
82
|
+
/** 計畫修正者:ring 策略隨機挑一位審查者以外的 agent;author 策略交回計畫作者 */
|
|
51
83
|
export function planFixAgent(cycle, opts) {
|
|
52
84
|
if (opts.strategy === "author")
|
|
53
85
|
return opts.planWriter ?? cycle[0];
|
|
54
|
-
return
|
|
86
|
+
return pick(cycle, opts.seed, opts.planReviewer ? [opts.planReviewer] : []);
|
|
55
87
|
}
|
|
56
88
|
/**
|
|
57
89
|
* 仲裁小組:
|
|
58
|
-
* - 有第三方(作者與最後審查者以外的 agent)→
|
|
90
|
+
* - 有第三方(作者與最後審查者以外的 agent)→ 隨機挑一位第三方單獨仲裁
|
|
59
91
|
* - 只有兩家 → 兩家各自在全新 context 中雙盲仲裁,避免讓一直反對的審查者同時當裁判
|
|
60
92
|
* - 只有一家 → 只能由它自己仲裁
|
|
61
93
|
*/
|
|
62
|
-
export function arbiterPanel(cycle, writer, reviewer) {
|
|
94
|
+
export function arbiterPanel(cycle, seed, writer, reviewer) {
|
|
63
95
|
const involved = [writer, reviewer].filter((x) => Boolean(x));
|
|
64
|
-
const third = cycle.find((c) => !involved.includes(c));
|
|
96
|
+
const third = shuffled(cycle, seed).find((c) => !involved.includes(c));
|
|
65
97
|
if (third)
|
|
66
98
|
return [third];
|
|
67
99
|
return [...new Set(cycle)];
|
|
68
100
|
}
|
|
69
101
|
/**
|
|
70
|
-
* 代打人選:原本的 agent
|
|
102
|
+
* 代打人選:原本的 agent 可用就用它;額度用完時,隨機挑一位還有額度的 agent。
|
|
71
103
|
* 全部都用完時回傳 undefined。
|
|
72
104
|
*/
|
|
73
|
-
export function availableAgent(cycle, preferred, exhausted) {
|
|
105
|
+
export function availableAgent(cycle, preferred, exhausted, seed) {
|
|
74
106
|
if (!exhausted.includes(preferred))
|
|
75
107
|
return preferred;
|
|
76
|
-
|
|
77
|
-
return exhausted.includes(next) ? undefined : next;
|
|
108
|
+
return shuffled(cycle, seed).find((c) => !exhausted.includes(c));
|
|
78
109
|
}
|
|
79
110
|
//# sourceMappingURL=roles.js.map
|
package/dist/runner.js
CHANGED
|
@@ -59,7 +59,8 @@ export function resolveAgent(cfg, name) {
|
|
|
59
59
|
const def = cfg.agents[name];
|
|
60
60
|
if (!def)
|
|
61
61
|
throw new Error(`未定義的 agent:${name}(請先用 agent add ${name} --adapter <adapter> 新增)`);
|
|
62
|
-
|
|
62
|
+
const defaultModel = def.adapter === "command" ? undefined : cfg.defaultModels[def.adapter];
|
|
63
|
+
return { ...def, model: def.model ?? defaultModel };
|
|
63
64
|
}
|
|
64
65
|
/** 確認某個 agent 的 CLI 是否可以執行 */
|
|
65
66
|
export async function probeAgent(def) {
|
package/dist/schemas.js
CHANGED
|
@@ -14,6 +14,50 @@ export const Stage = z.enum([
|
|
|
14
14
|
"done",
|
|
15
15
|
"failed",
|
|
16
16
|
]);
|
|
17
|
+
export const HandoffSource = z.object({
|
|
18
|
+
stage: Stage,
|
|
19
|
+
step: z.string().min(1),
|
|
20
|
+
agent: z.string().min(1),
|
|
21
|
+
callKey: z.string().min(1),
|
|
22
|
+
});
|
|
23
|
+
const HandoffKind = z.enum(["action", "info"]);
|
|
24
|
+
const HandoffTarget = z.enum(["plan", "code"]);
|
|
25
|
+
const HandoffStatus = z.enum(["open", "proposed_resolved", "resolved", "accepted"]);
|
|
26
|
+
export const HandoffResponse = z.object({
|
|
27
|
+
newIssues: z.array(z.object({
|
|
28
|
+
kind: HandoffKind,
|
|
29
|
+
summary: z.string().trim().min(1),
|
|
30
|
+
evidence: z.string().trim().min(1),
|
|
31
|
+
targetStage: HandoffTarget,
|
|
32
|
+
})),
|
|
33
|
+
dispositions: z.array(z.object({
|
|
34
|
+
id: z.string().min(1),
|
|
35
|
+
status: z.enum(["proposed_resolved", "resolved", "accepted"]),
|
|
36
|
+
reason: z.string().trim().min(1),
|
|
37
|
+
evidence: z.string().trim().min(1),
|
|
38
|
+
})),
|
|
39
|
+
});
|
|
40
|
+
export const HandoffIssue = z.object({
|
|
41
|
+
id: z.string().min(1),
|
|
42
|
+
source: HandoffSource,
|
|
43
|
+
kind: HandoffKind,
|
|
44
|
+
summary: z.string().min(1),
|
|
45
|
+
evidence: z.string().min(1),
|
|
46
|
+
targetStage: HandoffTarget,
|
|
47
|
+
status: HandoffStatus,
|
|
48
|
+
resolution: z.object({
|
|
49
|
+
agent: z.string(),
|
|
50
|
+
reason: z.string(),
|
|
51
|
+
evidence: z.string(),
|
|
52
|
+
}).optional(),
|
|
53
|
+
updatedAt: z.string(),
|
|
54
|
+
});
|
|
55
|
+
export const HandoffLedger = z.object({
|
|
56
|
+
version: z.literal(1),
|
|
57
|
+
issues: z.array(HandoffIssue),
|
|
58
|
+
/** 用來辨識沒有新增事項的回覆是否已經合併。 */
|
|
59
|
+
appliedCalls: z.array(z.string()).optional(),
|
|
60
|
+
});
|
|
17
61
|
/** Agent 在 spec 階段產出的 .flow/acceptance.json */
|
|
18
62
|
export const AcceptanceList = z
|
|
19
63
|
.array(z.object({
|
|
@@ -39,7 +83,12 @@ export const ReviewResult = z.object({
|
|
|
39
83
|
note: z.string().default(""),
|
|
40
84
|
})),
|
|
41
85
|
});
|
|
42
|
-
/**
|
|
86
|
+
/** 仲裁者可能用 reject 表示否決;讀取時正規化,保留相同的理由欄位。 */
|
|
87
|
+
export const ArbiterResult = ReviewResult.extend({
|
|
88
|
+
verdict: z.enum(["approve", "changes_requested", "reject"])
|
|
89
|
+
.transform((verdict) => verdict === "reject" ? "changes_requested" : verdict),
|
|
90
|
+
});
|
|
91
|
+
/** 一個 agent 的定義;名稱(agents 的 key)用在 cycle 裡 */
|
|
43
92
|
export const AgentDef = z.object({
|
|
44
93
|
adapter: z.enum(["claude", "codex", "gemini", "command"]),
|
|
45
94
|
model: z.string().optional(),
|
|
@@ -51,7 +100,13 @@ export const AgentDef = z.object({
|
|
|
51
100
|
export const RepoConfig = z.object({
|
|
52
101
|
/** 可用的 agent;沒有內建,全部都要在這裡定義(通常用 agent add) */
|
|
53
102
|
agents: z.record(z.string(), AgentDef).default({}),
|
|
54
|
-
/**
|
|
103
|
+
/** 各 CLI adapter 的預設模型;agent 自己指定 model 時優先使用個別設定 */
|
|
104
|
+
defaultModels: z.strictObject({
|
|
105
|
+
claude: z.string().trim().min(1).optional(),
|
|
106
|
+
codex: z.string().trim().min(1).optional(),
|
|
107
|
+
gemini: z.string().trim().min(1).optional(),
|
|
108
|
+
}).default({}),
|
|
109
|
+
/** 參與的 agent(順序不影響分工);未設定時取 agents 裡已安裝的 CLI */
|
|
55
110
|
cycle: z.array(z.string()).min(1).optional(),
|
|
56
111
|
/** review 後的修正由誰做:ring=輪到下一位;author=最後寫程式的 agent */
|
|
57
112
|
fixStrategy: z.enum(["ring", "author"]).default("ring"),
|
|
@@ -94,7 +149,7 @@ export const FlowRun = z.object({
|
|
|
94
149
|
/** 暫停前所在的階段與原因(額度用完時) */
|
|
95
150
|
pausedStage: Stage.optional(),
|
|
96
151
|
pauseReason: z.string().optional(),
|
|
97
|
-
/** 這個 run
|
|
152
|
+
/** 這個 run 參與的 agent(建立時決定,resume 時沿用) */
|
|
98
153
|
cycle: z.array(z.string()).min(1),
|
|
99
154
|
/** 最後一個寫程式的 agent,reviewer 不可以是它 */
|
|
100
155
|
lastWriter: z.string().optional(),
|
package/dist/setup.js
CHANGED
|
@@ -46,7 +46,7 @@ export async function runSetup(initial, deps) {
|
|
|
46
46
|
return null;
|
|
47
47
|
}
|
|
48
48
|
for (;;) {
|
|
49
|
-
const list = (await ask("
|
|
49
|
+
const list = (await ask("參與的 agent,用逗號分隔", chosen.join(","))).split(",").map((s) => s.trim()).filter(Boolean);
|
|
50
50
|
try {
|
|
51
51
|
cfg = setCycle(cfg, list).cfg;
|
|
52
52
|
break;
|
|
@@ -59,7 +59,7 @@ export async function runSetup(initial, deps) {
|
|
|
59
59
|
log("\n即將寫入:");
|
|
60
60
|
for (const name of chosen)
|
|
61
61
|
log(` ${name.padEnd(14)} adapter=${agents[name].adapter}${agents[name].model ? ` model=${agents[name].model}` : ""}`);
|
|
62
|
-
log(`
|
|
62
|
+
log(` 參與的 agent:${cfg.cycle.join("、")}`);
|
|
63
63
|
log(" 需要自訂指令的 CLI 請改用 agent add <name> --adapter command -- <指令>");
|
|
64
64
|
if (!(await confirm("寫入 flow.config.json?", true))) {
|
|
65
65
|
log("已取消,設定沒有變更");
|
package/package.json
CHANGED
package/prompts/fix.md
CHANGED
|
@@ -6,6 +6,17 @@
|
|
|
6
6
|
目前的工作目錄就是專案(agentflowctl 為這次任務建立的專用 git worktree)。
|
|
7
7
|
</context>
|
|
8
8
|
|
|
9
|
+
<handoff>
|
|
10
|
+
先閱讀 .flow/handoff-context.md,處理與本階段有關的待辦事項。完成時寫入 .flow/handoff-response.json;即使沒有事項也必須寫出空陣列:
|
|
11
|
+
|
|
12
|
+
```json
|
|
13
|
+
{ "newIssues": [], "dispositions": [] }
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
新增事項格式:{ "kind": "action 或 info", "summary": "具體問題", "evidence": "檔案位置或檢查證據", "targetStage": "plan 或 code" }。
|
|
17
|
+
處置格式:{ "id": "既有事項 ID", "status": "proposed_resolved、resolved 或 accepted", "reason": "具體處理理由", "evidence": "檔案、commit 或檢查結果" }。撰寫者只能用 proposed_resolved 提出修正;審查者可以用 resolved 或 accepted 結案。重要疑慮必須放在這份檔案,不能只寫在回覆的 <concerns>。
|
|
18
|
+
</handoff>
|
|
19
|
+
|
|
9
20
|
<inputs>
|
|
10
21
|
- .flow/feedback.md:失敗的檢查(型別、lint、測試、建置)或審查意見
|
|
11
22
|
- .flow/spec.md 與 .flow/acceptance.json:規格
|
|
@@ -6,6 +6,17 @@
|
|
|
6
6
|
目前的工作目錄就是專案(agentflowctl 為這次任務建立的專用 git worktree)。
|
|
7
7
|
</context>
|
|
8
8
|
|
|
9
|
+
<handoff>
|
|
10
|
+
先閱讀 .flow/handoff-context.md,處理與本階段有關的待辦事項。完成時寫入 .flow/handoff-response.json;即使沒有事項也必須寫出空陣列:
|
|
11
|
+
|
|
12
|
+
```json
|
|
13
|
+
{ "newIssues": [], "dispositions": [] }
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
新增事項格式:{ "kind": "action 或 info", "summary": "具體問題", "evidence": "檔案位置或檢查證據", "targetStage": "plan 或 code" }。
|
|
17
|
+
處置格式:{ "id": "既有事項 ID", "status": "proposed_resolved、resolved 或 accepted", "reason": "具體處理理由", "evidence": "檔案、commit 或檢查結果" }。撰寫者只能用 proposed_resolved 提出修正;審查者可以用 resolved 或 accepted 結案。重要疑慮必須放在這份檔案,不能只寫在回覆的 <concerns>。
|
|
18
|
+
</handoff>
|
|
19
|
+
|
|
9
20
|
<task>
|
|
10
21
|
```json
|
|
11
22
|
{{task}}
|
|
@@ -6,6 +6,17 @@
|
|
|
6
6
|
目前的工作目錄就是專案(agentflowctl 為這次任務建立的專用 git worktree)。
|
|
7
7
|
</context>
|
|
8
8
|
|
|
9
|
+
<handoff>
|
|
10
|
+
先閱讀 .flow/handoff-context.md,處理與本階段有關的待辦事項。完成時寫入 .flow/handoff-response.json;即使沒有事項也必須寫出空陣列:
|
|
11
|
+
|
|
12
|
+
```json
|
|
13
|
+
{ "newIssues": [], "dispositions": [] }
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
新增事項格式:{ "kind": "action 或 info", "summary": "具體問題", "evidence": "檔案位置或檢查證據", "targetStage": "plan 或 code" }。
|
|
17
|
+
處置格式:{ "id": "既有事項 ID", "status": "proposed_resolved、resolved 或 accepted", "reason": "具體處理理由", "evidence": "檔案、commit 或檢查結果" }。撰寫者只能用 proposed_resolved 提出修正;審查者可以用 resolved 或 accepted 結案。重要疑慮必須放在這份檔案,不能只寫在回覆的 <concerns>。
|
|
18
|
+
</handoff>
|
|
19
|
+
|
|
9
20
|
<task>
|
|
10
21
|
```json
|
|
11
22
|
{{task}}
|
package/prompts/plan-arbiter.md
CHANGED
|
@@ -6,6 +6,17 @@
|
|
|
6
6
|
目前的工作目錄就是專案(agentflowctl 為這次任務建立的專用 git worktree)。
|
|
7
7
|
</context>
|
|
8
8
|
|
|
9
|
+
<handoff>
|
|
10
|
+
先閱讀 .flow/handoff-context.md,處理與本階段有關的待辦事項。完成時寫入 .flow/handoff-response.json;即使沒有事項也必須寫出空陣列:
|
|
11
|
+
|
|
12
|
+
```json
|
|
13
|
+
{ "newIssues": [], "dispositions": [] }
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
新增事項格式:{ "kind": "action 或 info", "summary": "具體問題", "evidence": "檔案位置或檢查證據", "targetStage": "plan 或 code" }。
|
|
17
|
+
處置格式:{ "id": "既有事項 ID", "status": "proposed_resolved、resolved 或 accepted", "reason": "具體處理理由", "evidence": "檔案、commit 或檢查結果" }。撰寫者只能用 proposed_resolved 提出修正;審查者可以用 resolved 或 accepted 結案。重要疑慮必須放在這份檔案,不能只寫在回覆的 <concerns>。
|
|
18
|
+
</handoff>
|
|
19
|
+
|
|
9
20
|
<requirement>
|
|
10
21
|
{{requirement}}
|
|
11
22
|
</requirement>
|
|
@@ -36,10 +47,11 @@
|
|
|
36
47
|
```
|
|
37
48
|
|
|
38
49
|
dispute.md 裡的每一條意見都要列一筆並說明你的判斷。
|
|
50
|
+
`verdict` 只能寫 `approve` 或 `changes_requested`。若計畫有會導致錯誤結果、遺漏需求或無法驗收的問題,請寫 `changes_requested`,不要寫 `reject`。
|
|
39
51
|
</output_format>
|
|
40
52
|
|
|
41
53
|
<constraints>
|
|
42
|
-
- 只能寫入 .flow/plan-arbiter.json,不可修改規格、計畫或任何程式碼。
|
|
54
|
+
- 只能寫入 .flow/plan-arbiter.json 與 .flow/handoff-response.json,不可修改規格、計畫或任何程式碼。
|
|
43
55
|
</constraints>
|
|
44
56
|
|
|
45
57
|
<reply_format>
|
package/prompts/plan-fix.md
CHANGED
|
@@ -6,6 +6,17 @@
|
|
|
6
6
|
目前的工作目錄就是專案(agentflowctl 為這次任務建立的專用 git worktree)。
|
|
7
7
|
</context>
|
|
8
8
|
|
|
9
|
+
<handoff>
|
|
10
|
+
先閱讀 .flow/handoff-context.md,處理與本階段有關的待辦事項。完成時寫入 .flow/handoff-response.json;即使沒有事項也必須寫出空陣列:
|
|
11
|
+
|
|
12
|
+
```json
|
|
13
|
+
{ "newIssues": [], "dispositions": [] }
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
新增事項格式:{ "kind": "action 或 info", "summary": "具體問題", "evidence": "檔案位置或檢查證據", "targetStage": "plan 或 code" }。
|
|
17
|
+
處置格式:{ "id": "既有事項 ID", "status": "proposed_resolved、resolved 或 accepted", "reason": "具體處理理由", "evidence": "檔案、commit 或檢查結果" }。撰寫者只能用 proposed_resolved 提出修正;審查者可以用 resolved 或 accepted 結案。重要疑慮必須放在這份檔案,不能只寫在回覆的 <concerns>。
|
|
18
|
+
</handoff>
|
|
19
|
+
|
|
9
20
|
<requirement>
|
|
10
21
|
{{requirement}}
|
|
11
22
|
</requirement>
|
package/prompts/plan-review.md
CHANGED
|
@@ -6,6 +6,17 @@
|
|
|
6
6
|
目前的工作目錄就是專案(agentflowctl 為這次任務建立的專用 git worktree)。
|
|
7
7
|
</context>
|
|
8
8
|
|
|
9
|
+
<handoff>
|
|
10
|
+
先閱讀 .flow/handoff-context.md,處理與本階段有關的待辦事項。完成時寫入 .flow/handoff-response.json;即使沒有事項也必須寫出空陣列:
|
|
11
|
+
|
|
12
|
+
```json
|
|
13
|
+
{ "newIssues": [], "dispositions": [] }
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
新增事項格式:{ "kind": "action 或 info", "summary": "具體問題", "evidence": "檔案位置或檢查證據", "targetStage": "plan 或 code" }。
|
|
17
|
+
處置格式:{ "id": "既有事項 ID", "status": "proposed_resolved、resolved 或 accepted", "reason": "具體處理理由", "evidence": "檔案、commit 或檢查結果" }。撰寫者只能用 proposed_resolved 提出修正;審查者可以用 resolved 或 accepted 結案。重要疑慮必須放在這份檔案,不能只寫在回覆的 <concerns>。
|
|
18
|
+
</handoff>
|
|
19
|
+
|
|
9
20
|
<requirement>
|
|
10
21
|
{{requirement}}
|
|
11
22
|
</requirement>
|
|
@@ -46,7 +57,7 @@
|
|
|
46
57
|
</output_format>
|
|
47
58
|
|
|
48
59
|
<constraints>
|
|
49
|
-
- 只能寫入 .flow/plan-review.json,不可修改規格、計畫或任何程式碼,其他變更都會被還原。
|
|
60
|
+
- 只能寫入 .flow/plan-review.json 與 .flow/handoff-response.json,不可修改規格、計畫或任何程式碼,其他變更都會被還原。
|
|
50
61
|
</constraints>
|
|
51
62
|
|
|
52
63
|
<reply_format>
|
package/prompts/plan.md
CHANGED
|
@@ -6,6 +6,17 @@
|
|
|
6
6
|
目前的工作目錄就是專案(agentflowctl 為這次任務建立的專用 git worktree)。
|
|
7
7
|
</context>
|
|
8
8
|
|
|
9
|
+
<handoff>
|
|
10
|
+
先閱讀 .flow/handoff-context.md,處理與本階段有關的待辦事項。完成時寫入 .flow/handoff-response.json;即使沒有事項也必須寫出空陣列:
|
|
11
|
+
|
|
12
|
+
```json
|
|
13
|
+
{ "newIssues": [], "dispositions": [] }
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
新增事項格式:{ "kind": "action 或 info", "summary": "具體問題", "evidence": "檔案位置或檢查證據", "targetStage": "plan 或 code" }。
|
|
17
|
+
處置格式:{ "id": "既有事項 ID", "status": "proposed_resolved、resolved 或 accepted", "reason": "具體處理理由", "evidence": "檔案、commit 或檢查結果" }。撰寫者只能用 proposed_resolved 提出修正;審查者可以用 resolved 或 accepted 結案。重要疑慮必須放在這份檔案,不能只寫在回覆的 <concerns>。
|
|
18
|
+
</handoff>
|
|
19
|
+
|
|
9
20
|
<inputs>
|
|
10
21
|
- .flow/spec.md
|
|
11
22
|
- .flow/acceptance.json
|
package/prompts/review.md
CHANGED
|
@@ -6,6 +6,17 @@
|
|
|
6
6
|
目前的工作目錄就是專案(agentflowctl 為這次任務建立的專用 git worktree)。
|
|
7
7
|
</context>
|
|
8
8
|
|
|
9
|
+
<handoff>
|
|
10
|
+
先閱讀 .flow/handoff-context.md,處理與本階段有關的待辦事項。完成時寫入 .flow/handoff-response.json;即使沒有事項也必須寫出空陣列:
|
|
11
|
+
|
|
12
|
+
```json
|
|
13
|
+
{ "newIssues": [], "dispositions": [] }
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
新增事項格式:{ "kind": "action 或 info", "summary": "具體問題", "evidence": "檔案位置或檢查證據", "targetStage": "plan 或 code" }。
|
|
17
|
+
處置格式:{ "id": "既有事項 ID", "status": "proposed_resolved、resolved 或 accepted", "reason": "具體處理理由", "evidence": "檔案、commit 或檢查結果" }。撰寫者只能用 proposed_resolved 提出修正;審查者可以用 resolved 或 accepted 結案。重要疑慮必須放在這份檔案,不能只寫在回覆的 <concerns>。
|
|
18
|
+
</handoff>
|
|
19
|
+
|
|
9
20
|
<inputs>
|
|
10
21
|
- 規格:.flow/spec.md
|
|
11
22
|
- 驗收條件:.flow/acceptance.json
|
|
@@ -39,7 +50,7 @@
|
|
|
39
50
|
</output_format>
|
|
40
51
|
|
|
41
52
|
<constraints>
|
|
42
|
-
- 只能寫入 .flow/review.json,不可修改任何程式碼,其他變更都會被捨棄。
|
|
53
|
+
- 只能寫入 .flow/review.json 與 .flow/handoff-response.json,不可修改任何程式碼,其他變更都會被捨棄。
|
|
43
54
|
</constraints>
|
|
44
55
|
|
|
45
56
|
<reply_format>
|
package/prompts/spec.md
CHANGED
|
@@ -6,6 +6,17 @@
|
|
|
6
6
|
目前的工作目錄就是專案(agentflowctl 為這次任務建立的專用 git worktree)。
|
|
7
7
|
</context>
|
|
8
8
|
|
|
9
|
+
<handoff>
|
|
10
|
+
先閱讀 .flow/handoff-context.md,處理與本階段有關的待辦事項。完成時寫入 .flow/handoff-response.json;即使沒有事項也必須寫出空陣列:
|
|
11
|
+
|
|
12
|
+
```json
|
|
13
|
+
{ "newIssues": [], "dispositions": [] }
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
新增事項格式:{ "kind": "action 或 info", "summary": "具體問題", "evidence": "檔案位置或檢查證據", "targetStage": "plan 或 code" }。
|
|
17
|
+
處置格式:{ "id": "既有事項 ID", "status": "proposed_resolved、resolved 或 accepted", "reason": "具體處理理由", "evidence": "檔案、commit 或檢查結果" }。撰寫者只能用 proposed_resolved 提出修正;審查者可以用 resolved 或 accepted 結案。重要疑慮必須放在這份檔案,不能只寫在回覆的 <concerns>。
|
|
18
|
+
</handoff>
|
|
19
|
+
|
|
9
20
|
<requirement>
|
|
10
21
|
{{requirement}}
|
|
11
22
|
</requirement>
|