@mickorz/opencode-agentic-workflow 0.3.0 → 0.4.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 +5 -0
- package/dist/observability/events.d.ts +7 -0
- package/dist/observability/events.js.map +1 -1
- package/dist/plugin/checkpoint-override.d.ts +28 -0
- package/dist/plugin/checkpoint-override.js +49 -0
- package/dist/plugin/checkpoint-override.js.map +1 -0
- package/dist/plugin/index.js +28 -3
- package/dist/plugin/index.js.map +1 -1
- package/dist/quality/checkpoint.d.ts +4 -2
- package/dist/quality/checkpoint.js +5 -1
- package/dist/quality/checkpoint.js.map +1 -1
- package/dist/quality/verify.d.ts +35 -5
- package/dist/quality/verify.js +90 -14
- package/dist/quality/verify.js.map +1 -1
- package/dist/utils/string-case.d.ts +8 -0
- package/dist/utils/string-case.js +15 -0
- package/dist/utils/string-case.js.map +1 -0
- package/dist/utils/titlecase.d.ts +7 -0
- package/dist/utils/titlecase.js +15 -0
- package/dist/utils/titlecase.js.map +1 -0
- package/dist/workflows/feature-development.d.ts +59 -0
- package/dist/workflows/feature-development.js +248 -0
- package/dist/workflows/feature-development.js.map +1 -0
- package/dist/workspace/in-place.d.ts +26 -0
- package/dist/workspace/in-place.js +48 -0
- package/dist/workspace/in-place.js.map +1 -0
- package/dist/workspace/index.d.ts +1 -0
- package/dist/workspace/index.js +1 -0
- package/dist/workspace/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -137,9 +137,14 @@ npm install && npm run build # 产物在 dist/plugin
|
|
|
137
137
|
| `smoke` | research → summary | 3 路并行分析 agent + 1 个汇总 agent(冒烟演示) |
|
|
138
138
|
| `reliable` | execute → check → verify → checkpoint | agent 执行 → 确定性检查 → 多 reviewer 语义评审 → 审批 |
|
|
139
139
|
| `artifact` | write → check → checkpoint | 在隔离 workspace 中生成文件产物并验证(隔离验收载体) |
|
|
140
|
+
| `feature-development` ⭐ | analyze → implement → check → verify → checkpoint | 一句话需求 → 隔离 worktree 实现 → 真实测试 → 失败自动修复 → reviewer 审查真实 diff → 人工审批;产物固化为 `agw/<runId>` 分支 commit(需启用 isolation) |
|
|
140
141
|
|
|
141
142
|
新增 workflow = 在 `src/workflows/` 写一个 `WorkflowDefinition` 并在
|
|
142
143
|
`src/plugin/index.ts` 注册;工具描述、枚举、路由全部由注册表驱动。
|
|
144
|
+
编写规范与事故教训见 **[Workflow Authoring Best Practices](./docs/workflow-authoring.md)**。
|
|
145
|
+
|
|
146
|
+
遇到「改了代码不生效」「插件版本不对」「checkpoint 卡 5 分钟」等问题,
|
|
147
|
+
先查 **[Troubleshooting](./docs/troubleshooting.md)**。
|
|
143
148
|
|
|
144
149
|
---
|
|
145
150
|
|
|
@@ -57,6 +57,13 @@ export type WorkflowEvent = WorkflowEventBase & ({
|
|
|
57
57
|
passed: boolean;
|
|
58
58
|
passedCount: number;
|
|
59
59
|
totalCount: number;
|
|
60
|
+
} | {
|
|
61
|
+
/** v0.3.1 坑 3:reviewer 协议失败(解析重试耗尽)——非语义否决 */
|
|
62
|
+
type: "verify.protocol_failed";
|
|
63
|
+
label: string;
|
|
64
|
+
reviewer: number;
|
|
65
|
+
attempts: number;
|
|
66
|
+
lastRaw: string;
|
|
60
67
|
} | {
|
|
61
68
|
type: "checkpoint.waiting";
|
|
62
69
|
label: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/observability/events.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/observability/events.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AA+DH,+BAA+B;AAC/B,MAAM,UAAU,cAAc;IAC5B,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAgB,CAAA;IACxC,OAAO;QACL,QAAQ,CAAC,KAAoB;YAC3B,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;gBAC/B,IAAI,CAAC;oBACH,OAAO,CAAC,KAAK,CAAC,CAAA;gBAChB,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,4BAA4B;oBAC5B,OAAO,CAAC,GAAG,CACT,8CAA8C,KAAK,CAAC,IAAI,IAAI;wBAC1D,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAC9D,CAAA;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QACD,SAAS,CAAC,OAAqB;YAC7B,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;YACrB,OAAO,GAAG,EAAE;gBACV,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;YAC1B,CAAC,CAAA;QACH,CAAC;KACF,CAAA;AACH,CAAC;AAED,IAAI,UAAU,GAAa,cAAc,EAAE,CAAA;AAE3C,wBAAwB;AACxB,MAAM,UAAU,WAAW,CAAC,GAAa;IACvC,UAAU,GAAG,GAAG,CAAA;AAClB,CAAC;AAED,eAAe;AACf,MAAM,UAAU,WAAW;IACzB,OAAO,UAAU,CAAA;AACnB,CAAC;AAED,qBAAqB;AACrB,MAAM,UAAU,SAAS,CAAC,KAAiB;IACzC,UAAU,CAAC,QAAQ,CAAC,EAAE,GAAG,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,EAAmB,CAAC,CAAA;AACtE,CAAC;AAED,4BAA4B;AAC5B,MAAM,UAAU,OAAO,CAAC,IAAY,EAAE,GAAG,GAAG,EAAE;IAC5C,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAA;IAClD,OAAO,SAAS,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAA;AAC5E,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* checkpoint 覆盖(P3 Blocker 修复:守护进程单例投毒)
|
|
3
|
+
*
|
|
4
|
+
* 背景:插件在 init 时把 checkpoint gate 绑成 module 单例;OpenCode 的
|
|
5
|
+
* 长驻 server 进程可能附着旧插件实例,新项目的 opencode.json 配置
|
|
6
|
+
* (checkpoint.mode 等)被完全无视——实测 auto-approve 被静默替换成
|
|
7
|
+
* 交互门(5 分钟超时假失败)+ 观测数据写进别的项目。
|
|
8
|
+
*
|
|
9
|
+
* 修复策略:**运行时显式 > 环境隐式**。workflow 工具新增保留参数
|
|
10
|
+
* `checkpointMode`,调用时显式覆盖本次运行的审批门,结束恢复原绑定。
|
|
11
|
+
* 对守护进程宿主天然免疫(参数随调用走,不依赖 init 快照)。
|
|
12
|
+
*
|
|
13
|
+
* 范围收敛(v0.4.0):只支持策略门(auto-approve / auto-reject)——
|
|
14
|
+
* interactive 门需要 RPC 域 + bind() 注册,按调用创建会累积 RPC
|
|
15
|
+
* 注册且无 unbind 通道,保持「仅限插件配置」。
|
|
16
|
+
*
|
|
17
|
+
* 已知限制:全局 gate 仍是单例,两个并发调用携带不同覆盖值时存在
|
|
18
|
+
* 竞态(restore 交叠)。per-run gate 线程化是后续 L 范围工作;
|
|
19
|
+
* 单会话 `opencode run` / TUI 串行场景不受影响。
|
|
20
|
+
*/
|
|
21
|
+
/** 可作为调用级覆盖的审批模式(策略门子集) */
|
|
22
|
+
export type CheckpointModeOverride = "auto-approve" | "auto-reject";
|
|
23
|
+
export declare function parseCheckpointModeOverride(value: unknown): CheckpointModeOverride | undefined;
|
|
24
|
+
/**
|
|
25
|
+
* 为**本次**调用绑定覆盖门;返回恢复函数(无覆盖时返回 undefined)。
|
|
26
|
+
* 必须在 finally 中调用恢复函数,防止覆盖泄漏到后续调用。
|
|
27
|
+
*/
|
|
28
|
+
export declare function applyCheckpointModeOverride(mode: CheckpointModeOverride | undefined): (() => void) | undefined;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* checkpoint 覆盖(P3 Blocker 修复:守护进程单例投毒)
|
|
3
|
+
*
|
|
4
|
+
* 背景:插件在 init 时把 checkpoint gate 绑成 module 单例;OpenCode 的
|
|
5
|
+
* 长驻 server 进程可能附着旧插件实例,新项目的 opencode.json 配置
|
|
6
|
+
* (checkpoint.mode 等)被完全无视——实测 auto-approve 被静默替换成
|
|
7
|
+
* 交互门(5 分钟超时假失败)+ 观测数据写进别的项目。
|
|
8
|
+
*
|
|
9
|
+
* 修复策略:**运行时显式 > 环境隐式**。workflow 工具新增保留参数
|
|
10
|
+
* `checkpointMode`,调用时显式覆盖本次运行的审批门,结束恢复原绑定。
|
|
11
|
+
* 对守护进程宿主天然免疫(参数随调用走,不依赖 init 快照)。
|
|
12
|
+
*
|
|
13
|
+
* 范围收敛(v0.4.0):只支持策略门(auto-approve / auto-reject)——
|
|
14
|
+
* interactive 门需要 RPC 域 + bind() 注册,按调用创建会累积 RPC
|
|
15
|
+
* 注册且无 unbind 通道,保持「仅限插件配置」。
|
|
16
|
+
*
|
|
17
|
+
* 已知限制:全局 gate 仍是单例,两个并发调用携带不同覆盖值时存在
|
|
18
|
+
* 竞态(restore 交叠)。per-run gate 线程化是后续 L 范围工作;
|
|
19
|
+
* 单会话 `opencode run` / TUI 串行场景不受影响。
|
|
20
|
+
*/
|
|
21
|
+
import { getCheckpointGate, setCheckpointGate } from "../quality/checkpoint.js";
|
|
22
|
+
import { PolicyCheckpointGate } from "./policy-checkpoint-gate.js";
|
|
23
|
+
export function parseCheckpointModeOverride(value) {
|
|
24
|
+
if (value === undefined || value === null || value === "")
|
|
25
|
+
return undefined;
|
|
26
|
+
if (value === "auto-approve" || value === "auto-reject")
|
|
27
|
+
return value;
|
|
28
|
+
if (value === "interactive") {
|
|
29
|
+
console.log("[agentic-workflow] checkpointMode=interactive is not available as an " +
|
|
30
|
+
"invocation override (requires TUI plugin config); ignoring");
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
console.log(`[agentic-workflow] invalid checkpointMode override ignored: ${String(value)}`);
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* 为**本次**调用绑定覆盖门;返回恢复函数(无覆盖时返回 undefined)。
|
|
38
|
+
* 必须在 finally 中调用恢复函数,防止覆盖泄漏到后续调用。
|
|
39
|
+
*/
|
|
40
|
+
export function applyCheckpointModeOverride(mode) {
|
|
41
|
+
if (!mode)
|
|
42
|
+
return undefined;
|
|
43
|
+
const previous = getCheckpointGate();
|
|
44
|
+
setCheckpointGate(new PolicyCheckpointGate(mode));
|
|
45
|
+
console.log(`[agentic-workflow] checkpoint gate override for this invocation: ${mode} ` +
|
|
46
|
+
"(explicit per-call control; init-time config may differ)");
|
|
47
|
+
return () => setCheckpointGate(previous);
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=checkpoint-override.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkpoint-override.js","sourceRoot":"","sources":["../../src/plugin/checkpoint-override.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC/E,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAA;AAKlE,MAAM,UAAU,2BAA2B,CACzC,KAAc;IAEd,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,EAAE;QAAE,OAAO,SAAS,CAAA;IAC3E,IAAI,KAAK,KAAK,cAAc,IAAI,KAAK,KAAK,aAAa;QAAE,OAAO,KAAK,CAAA;IACrE,IAAI,KAAK,KAAK,aAAa,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,CACT,uEAAuE;YACrE,4DAA4D,CAC/D,CAAA;QACD,OAAO,SAAS,CAAA;IAClB,CAAC;IACD,OAAO,CAAC,GAAG,CACT,+DAA+D,MAAM,CAAC,KAAK,CAAC,EAAE,CAC/E,CAAA;IACD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,2BAA2B,CACzC,IAAwC;IAExC,IAAI,CAAC,IAAI;QAAE,OAAO,SAAS,CAAA;IAC3B,MAAM,QAAQ,GAAG,iBAAiB,EAAE,CAAA;IACpC,iBAAiB,CAAC,IAAI,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAA;IACjD,OAAO,CAAC,GAAG,CACT,oEAAoE,IAAI,GAAG;QACzE,0DAA0D,CAC7D,CAAA;IACD,OAAO,GAAG,EAAE,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAA;AAC1C,CAAC"}
|
package/dist/plugin/index.js
CHANGED
|
@@ -33,8 +33,10 @@ import { FileExecutionStore } from "../state/file-store.js";
|
|
|
33
33
|
import { reliableWorkflow } from "../workflows/reliable.js";
|
|
34
34
|
import { smokeWorkflow } from "../workflows/smoke.js";
|
|
35
35
|
import { artifactWorkflow } from "../workflows/artifact.js";
|
|
36
|
-
import {
|
|
36
|
+
import { featureDevelopmentWorkflow } from "../workflows/feature-development.js";
|
|
37
|
+
import { GitWorktreeProvider, InPlaceWorkspaceProvider } from "../workspace/index.js";
|
|
37
38
|
import { InteractiveCheckpointGate, } from "./interactive-checkpoint-gate.js";
|
|
39
|
+
import { applyCheckpointModeOverride, parseCheckpointModeOverride, } from "./checkpoint-override.js";
|
|
38
40
|
import { OpenCodeV2Executor } from "./opencode-v2-executor.js";
|
|
39
41
|
import { buildPriceTable, estimateCostUSD } from "./price-table.js";
|
|
40
42
|
import { PolicyCheckpointGate } from "./policy-checkpoint-gate.js";
|
|
@@ -115,7 +117,8 @@ export default Plugin.define({
|
|
|
115
117
|
const registry = new WorkflowRegistry()
|
|
116
118
|
.register(smokeWorkflow())
|
|
117
119
|
.register(reliableWorkflow({ checkCommand: options.checkCommand }))
|
|
118
|
-
.register(artifactWorkflow())
|
|
120
|
+
.register(artifactWorkflow())
|
|
121
|
+
.register(featureDevelopmentWorkflow({ checkCommand: options.checkCommand }));
|
|
119
122
|
// P2.5 durable journal:配置 journalDir 后,run 经 startWorkflow/resumeWorkflow
|
|
120
123
|
// 走持久化链路(journal 记录 workflow {id, version} + args + steps,可恢复)
|
|
121
124
|
let store;
|
|
@@ -127,7 +130,11 @@ export default Plugin.define({
|
|
|
127
130
|
console.log(`[agentic-workflow] journal store: ${journalDir}`);
|
|
128
131
|
}
|
|
129
132
|
// P2.7 workspace 隔离:GitWorktreeProvider(startDir = 项目目录,
|
|
130
|
-
// 内部解析到 git 仓库根;worktree
|
|
133
|
+
// 内部解析到 git 仓库根;worktree 落在仓库同级目录,不污染仓库)。
|
|
134
|
+
// P3 Blocker 修复:无隔离时绑定 InPlaceWorkspaceProvider——
|
|
135
|
+
// workspaceRoot 必须解析到项目目录;process.cwd() 在托管进程里
|
|
136
|
+
// 不是项目目录(长驻 server 场景实测为 HOME),artifact/reliable
|
|
137
|
+
// 等流程会「文件写对位置、check 查错位置」假失败。
|
|
131
138
|
let workspaceBinding;
|
|
132
139
|
if (options.isolation?.mode === "git-worktree") {
|
|
133
140
|
const dir = options.isolation.dir
|
|
@@ -143,6 +150,13 @@ export default Plugin.define({
|
|
|
143
150
|
console.log(`[agentic-workflow] workspace isolation: git-worktree ` +
|
|
144
151
|
`(cleanup=${options.isolation.cleanup ?? "on-success"}${dir ? `, dir=${dir}` : ""})`);
|
|
145
152
|
}
|
|
153
|
+
else {
|
|
154
|
+
workspaceBinding = {
|
|
155
|
+
provider: new InPlaceWorkspaceProvider({ startDir: ctx.location.directory }),
|
|
156
|
+
cleanup: "never",
|
|
157
|
+
};
|
|
158
|
+
console.log(`[agentic-workflow] workspace: in-place (project dir, no isolation)`);
|
|
159
|
+
}
|
|
146
160
|
// 递归防护:workflow 运行期间,子会话里的 agent 也可能看到并调用 workflow 工具,
|
|
147
161
|
// 形成递归 workflow;叠加并发信号量后会自饿死死锁(实测卡死)。
|
|
148
162
|
// P0 策略:运行中直接拒绝嵌套调用,让子 agent 用自身能力直接完成任务。
|
|
@@ -171,6 +185,13 @@ export default Plugin.define({
|
|
|
171
185
|
description: "Resume a previous durable run (from journal); overrides flow/topic. " +
|
|
172
186
|
"Use the runId reported by a failed workflow call",
|
|
173
187
|
},
|
|
188
|
+
checkpointMode: {
|
|
189
|
+
type: "string",
|
|
190
|
+
enum: ["auto-approve", "auto-reject"],
|
|
191
|
+
description: "Checkpoint gate mode for THIS invocation, overriding plugin config. " +
|
|
192
|
+
"Pass auto-approve for headless/opencode-run executions unless the user " +
|
|
193
|
+
"explicitly wants auto-reject. Ignored for flows without a checkpoint step",
|
|
194
|
+
},
|
|
174
195
|
},
|
|
175
196
|
},
|
|
176
197
|
// V2 强校验:Tool.Result 使用 output 字段必须声明 output schema,
|
|
@@ -187,6 +208,9 @@ export default Plugin.define({
|
|
|
187
208
|
};
|
|
188
209
|
}
|
|
189
210
|
workflowDepth += 1;
|
|
211
|
+
// P3 Blocker 修复:调用级 checkpoint 覆盖(守护进程宿主下
|
|
212
|
+
// init 配置可能来自别的项目——显式参数免疫单例投毒)
|
|
213
|
+
const gateRestore = applyCheckpointModeOverride(parseCheckpointModeOverride(parsed.checkpointMode));
|
|
190
214
|
try {
|
|
191
215
|
// resume 分支:journal -> registry 精确版本解析 -> 续跑
|
|
192
216
|
if (typeof parsed.resumeRunId === "string" && parsed.resumeRunId.length > 0) {
|
|
@@ -234,6 +258,7 @@ export default Plugin.define({
|
|
|
234
258
|
}
|
|
235
259
|
finally {
|
|
236
260
|
workflowDepth -= 1;
|
|
261
|
+
gateRestore?.();
|
|
237
262
|
}
|
|
238
263
|
},
|
|
239
264
|
});
|
package/dist/plugin/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/plugin/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACzC,OAAO,IAAI,MAAM,WAAW,CAAA;AAE5B,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAA;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAA;AAC/D,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAA;AACzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AACxF,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAA;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAE3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAC3D,OAAO,EAAE,mBAAmB,EAA8C,MAAM,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/plugin/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -33,8 +33,10 @@ export interface CheckpointOptions {
|
|
|
33
33
|
/** 节点标签,默认 "checkpoint" */
|
|
34
34
|
label?: string;
|
|
35
35
|
}
|
|
36
|
-
/** 注入 CheckpointGate(plugin
|
|
37
|
-
export declare function setCheckpointGate(value: CheckpointGate): void;
|
|
36
|
+
/** 注入 CheckpointGate(plugin 初始化时调用;传 undefined 表示解除绑定) */
|
|
37
|
+
export declare function setCheckpointGate(value: CheckpointGate | undefined): void;
|
|
38
|
+
/** 读取当前 gate(调用级覆盖需先保存原值以便恢复) */
|
|
39
|
+
export declare function getCheckpointGate(): CheckpointGate | undefined;
|
|
38
40
|
/** 获取当前 gate;未注入时抛错 */
|
|
39
41
|
export declare function requireCheckpointGate(): CheckpointGate;
|
|
40
42
|
/**
|
|
@@ -26,10 +26,14 @@ export class WorkflowCheckpointError extends WorkflowError {
|
|
|
26
26
|
}
|
|
27
27
|
/** ---- gate 注册(与 engine 的 executor 注入同构) ---- */
|
|
28
28
|
let gate;
|
|
29
|
-
/** 注入 CheckpointGate(plugin
|
|
29
|
+
/** 注入 CheckpointGate(plugin 初始化时调用;传 undefined 表示解除绑定) */
|
|
30
30
|
export function setCheckpointGate(value) {
|
|
31
31
|
gate = value;
|
|
32
32
|
}
|
|
33
|
+
/** 读取当前 gate(调用级覆盖需先保存原值以便恢复) */
|
|
34
|
+
export function getCheckpointGate() {
|
|
35
|
+
return gate;
|
|
36
|
+
}
|
|
33
37
|
/** 获取当前 gate;未注入时抛错 */
|
|
34
38
|
export function requireCheckpointGate() {
|
|
35
39
|
if (!gate) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkpoint.js","sourceRoot":"","sources":["../../src/quality/checkpoint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAA;AACtD,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAA;AAiB5C,mCAAmC;AACnC,MAAM,OAAO,uBAAwB,SAAQ,aAAa;IAC/C,KAAK,CAAQ;IACb,MAAM,CAAS;IAExB,YAAY,KAAa,EAAE,MAAe;QACxC,KAAK,CACH,wBAAwB,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CACjE,CAAA;QACD,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAA;QACrC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;QAClB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;IACtB,CAAC;CACF;AAOD,kDAAkD;AAElD,IAAI,IAAgC,CAAA;AAEpC,
|
|
1
|
+
{"version":3,"file":"checkpoint.js","sourceRoot":"","sources":["../../src/quality/checkpoint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAA;AACtD,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAA;AAiB5C,mCAAmC;AACnC,MAAM,OAAO,uBAAwB,SAAQ,aAAa;IAC/C,KAAK,CAAQ;IACb,MAAM,CAAS;IAExB,YAAY,KAAa,EAAE,MAAe;QACxC,KAAK,CACH,wBAAwB,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CACjE,CAAA;QACD,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAA;QACrC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;QAClB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;IACtB,CAAC;CACF;AAOD,kDAAkD;AAElD,IAAI,IAAgC,CAAA;AAEpC,0DAA0D;AAC1D,MAAM,UAAU,iBAAiB,CAAC,KAAiC;IACjE,IAAI,GAAG,KAAK,CAAA;AACd,CAAC;AAED,iCAAiC;AACjC,MAAM,UAAU,iBAAiB;IAC/B,OAAO,IAAI,CAAA;AACb,CAAC;AAED,uBAAuB;AACvB,MAAM,UAAU,qBAAqB;IACnC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CACb,6EAA6E,CAC9E,CAAA;IACH,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,OAAe,EACf,OAA2B;IAE3B,MAAM,KAAK,GAAG,OAAO,EAAE,KAAK,IAAI,YAAY,CAAA;IAC5C,KAAK,CAAC,cAAc,KAAK,GAAG,CAAC,CAAA;IAE7B,SAAS,CAAC,EAAE,IAAI,EAAE,oBAAoB,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAA;IAEzD,MAAM,QAAQ,GAAG,MAAM,qBAAqB,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAA;IAEtE,OAAO,CAAC,GAAG,CACT,iCAAiC,KAAK,KAAK,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,EAAE,CACzF,CAAA;IAED,SAAS,CAAC,EAAE,IAAI,EAAE,sBAAsB,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAA;IAE/E,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;QACvB,MAAM,IAAI,uBAAuB,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAA;IAC3D,CAAC;AACH,CAAC"}
|
package/dist/quality/verify.d.ts
CHANGED
|
@@ -6,14 +6,20 @@
|
|
|
6
6
|
* verify = 语义质量验证(reviewer agent 评审「做得对不对/好不好」)
|
|
7
7
|
*
|
|
8
8
|
* 机制:
|
|
9
|
-
* verify(artifact, { reviewers: N, criteria })
|
|
9
|
+
* verify(artifact, { reviewers: N, criteria, reviewerProtocol })
|
|
10
10
|
* -> N 个 reviewer 子 agent 并行评审(复用 parallel() 组合子)
|
|
11
|
-
* -> 每个 reviewer 被要求输出 JSON verdict
|
|
11
|
+
* -> 每个 reviewer 被要求输出 JSON verdict
|
|
12
|
+
* -> 三种结局严格分离(v0.3.1 坑 3 修复):
|
|
13
|
+
* a) 语义结论 pass/fail —— 不重试(拒绝就是拒绝,禁止「问到同意为止」)
|
|
14
|
+
* b) 解析失败(非法 JSON / 缺字段 / 非法 enum)—— 仅此类局部重试,
|
|
15
|
+
* 修复指令只要求重出格式,不重新评审;默认 attempts=2
|
|
16
|
+
* c) 重试耗尽 —— 抛 ReviewerProtocolError(协议失败),
|
|
17
|
+
* 绝不与「评审否决」混同:产物没有被否定,可安全 resume
|
|
12
18
|
* -> 全员 pass 才 passed=true(严格语义;后续失败策略在此之上构建)
|
|
13
19
|
*
|
|
14
20
|
* 与 check 对称的双 API:
|
|
15
|
-
* verify()
|
|
16
|
-
* assertVerify() ->
|
|
21
|
+
* verify() -> 语义结果永不抛错(协议失败除外:那不是评审结论,是运维事故)
|
|
22
|
+
* assertVerify() -> 语义失败抛 WorkflowVerifyError;协议失败原样上抛 ReviewerProtocolError
|
|
17
23
|
*/
|
|
18
24
|
import type { AgentResult } from "../runtime/executor.js";
|
|
19
25
|
import { WorkflowError } from "../runtime/errors.js";
|
|
@@ -32,6 +38,13 @@ export interface VerifyOptions {
|
|
|
32
38
|
criteria?: string;
|
|
33
39
|
/** 结果标签,默认 "semantic verify" */
|
|
34
40
|
label?: string;
|
|
41
|
+
/** reviewer 协议容错:解析失败时的局部重试策略(默认 attempts=2) */
|
|
42
|
+
reviewerProtocol?: ReviewerProtocolOptions;
|
|
43
|
+
}
|
|
44
|
+
/** reviewer 协议容错选项(只作用于解析失败,不作用于语义否决) */
|
|
45
|
+
export interface ReviewerProtocolOptions {
|
|
46
|
+
/** 单 reviewer 最大尝试次数(含首次),默认 2;最小 1(即不重试) */
|
|
47
|
+
attempts?: number;
|
|
35
48
|
}
|
|
36
49
|
export interface VerifyResult {
|
|
37
50
|
label: string;
|
|
@@ -44,7 +57,24 @@ export declare class WorkflowVerifyError extends WorkflowError {
|
|
|
44
57
|
readonly result: VerifyResult;
|
|
45
58
|
constructor(result: VerifyResult);
|
|
46
59
|
}
|
|
47
|
-
/**
|
|
60
|
+
/**
|
|
61
|
+
* reviewer 协议失败(解析重试耗尽)——与语义否决严格分离(v0.3.1 坑 3 修复)。
|
|
62
|
+
*
|
|
63
|
+
* 语义区别(用户可见诊断的关键):
|
|
64
|
+
* WorkflowVerifyError = 评审员看了产物,结论是「不合格」 → 产物被否定
|
|
65
|
+
* ReviewerProtocolError = 评审员的输出无法解析,评审没有完成 → 产物未被否定,可安全 resume
|
|
66
|
+
*/
|
|
67
|
+
export declare class ReviewerProtocolError extends WorkflowError {
|
|
68
|
+
readonly reviewer: number;
|
|
69
|
+
readonly attempts: number;
|
|
70
|
+
readonly lastRaw: string;
|
|
71
|
+
constructor(label: string, reviewer: number, attempts: number, lastRaw: string);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* 语义质量验证:N 个 reviewer 并行评审,全员 pass 才通过。
|
|
75
|
+
* 语义结果永不抛错;协议失败(解析重试耗尽)抛 ReviewerProtocolError——
|
|
76
|
+
* 那不是评审结论,是运维事故:产物未被否定,可安全 resume 重试 verify。
|
|
77
|
+
*/
|
|
48
78
|
export declare function verify(artifact: string | AgentResult | object, options?: VerifyOptions): Promise<VerifyResult>;
|
|
49
79
|
/** verify 的严格版:失败抛 WorkflowVerifyError,成功原样返回 VerifyResult */
|
|
50
80
|
export declare function assertVerify(artifact: string | AgentResult | object, options?: VerifyOptions): Promise<VerifyResult>;
|
package/dist/quality/verify.js
CHANGED
|
@@ -6,14 +6,20 @@
|
|
|
6
6
|
* verify = 语义质量验证(reviewer agent 评审「做得对不对/好不好」)
|
|
7
7
|
*
|
|
8
8
|
* 机制:
|
|
9
|
-
* verify(artifact, { reviewers: N, criteria })
|
|
9
|
+
* verify(artifact, { reviewers: N, criteria, reviewerProtocol })
|
|
10
10
|
* -> N 个 reviewer 子 agent 并行评审(复用 parallel() 组合子)
|
|
11
|
-
* -> 每个 reviewer 被要求输出 JSON verdict
|
|
11
|
+
* -> 每个 reviewer 被要求输出 JSON verdict
|
|
12
|
+
* -> 三种结局严格分离(v0.3.1 坑 3 修复):
|
|
13
|
+
* a) 语义结论 pass/fail —— 不重试(拒绝就是拒绝,禁止「问到同意为止」)
|
|
14
|
+
* b) 解析失败(非法 JSON / 缺字段 / 非法 enum)—— 仅此类局部重试,
|
|
15
|
+
* 修复指令只要求重出格式,不重新评审;默认 attempts=2
|
|
16
|
+
* c) 重试耗尽 —— 抛 ReviewerProtocolError(协议失败),
|
|
17
|
+
* 绝不与「评审否决」混同:产物没有被否定,可安全 resume
|
|
12
18
|
* -> 全员 pass 才 passed=true(严格语义;后续失败策略在此之上构建)
|
|
13
19
|
*
|
|
14
20
|
* 与 check 对称的双 API:
|
|
15
|
-
* verify()
|
|
16
|
-
* assertVerify() ->
|
|
21
|
+
* verify() -> 语义结果永不抛错(协议失败除外:那不是评审结论,是运维事故)
|
|
22
|
+
* assertVerify() -> 语义失败抛 WorkflowVerifyError;协议失败原样上抛 ReviewerProtocolError
|
|
17
23
|
*/
|
|
18
24
|
import { WorkflowError } from "../runtime/errors.js";
|
|
19
25
|
import { emitEvent } from "../observability/events.js";
|
|
@@ -34,6 +40,29 @@ export class WorkflowVerifyError extends WorkflowError {
|
|
|
34
40
|
this.result = result;
|
|
35
41
|
}
|
|
36
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* reviewer 协议失败(解析重试耗尽)——与语义否决严格分离(v0.3.1 坑 3 修复)。
|
|
45
|
+
*
|
|
46
|
+
* 语义区别(用户可见诊断的关键):
|
|
47
|
+
* WorkflowVerifyError = 评审员看了产物,结论是「不合格」 → 产物被否定
|
|
48
|
+
* ReviewerProtocolError = 评审员的输出无法解析,评审没有完成 → 产物未被否定,可安全 resume
|
|
49
|
+
*/
|
|
50
|
+
export class ReviewerProtocolError extends WorkflowError {
|
|
51
|
+
reviewer;
|
|
52
|
+
attempts;
|
|
53
|
+
lastRaw;
|
|
54
|
+
constructor(label, reviewer, attempts, lastRaw) {
|
|
55
|
+
super(`[workflow] verification could not be completed: reviewer #${reviewer} ` +
|
|
56
|
+
`returned invalid structured output after ${attempts} attempt` +
|
|
57
|
+
`${attempts > 1 ? "s" : ""} (label: ${label}). ` +
|
|
58
|
+
`This is a protocol failure, NOT a semantic rejection - ` +
|
|
59
|
+
`the artifact was not judged; resume to retry verify.`);
|
|
60
|
+
this.name = "ReviewerProtocolError";
|
|
61
|
+
this.reviewer = reviewer;
|
|
62
|
+
this.attempts = attempts;
|
|
63
|
+
this.lastRaw = lastRaw;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
37
66
|
/** 输入产物归一化为文本:string 原样,对象取 output 字段或 JSON 序列化 */
|
|
38
67
|
function artifactToText(artifact) {
|
|
39
68
|
if (typeof artifact === "string")
|
|
@@ -57,7 +86,11 @@ function buildReviewerPrompt(artifact, reviewerNo, reviewers, criteria) {
|
|
|
57
86
|
"pass 与 fail 只能二选一;没有问题时 issues 为空数组。",
|
|
58
87
|
].join("\n");
|
|
59
88
|
}
|
|
60
|
-
/**
|
|
89
|
+
/**
|
|
90
|
+
* 解析单个 reviewer 的输出为 verdict。
|
|
91
|
+
* 返回 undefined = 协议失败(非法 JSON / 缺字段 / 非法 enum)——
|
|
92
|
+
* 由调用方走局部重试,绝不在此伪造成「fail」(坑 3:协议失败 ≠ 评审否决)。
|
|
93
|
+
*/
|
|
61
94
|
function toVerdict(reviewer, output) {
|
|
62
95
|
const parsed = parseJsonLoose(output);
|
|
63
96
|
if (parsed &&
|
|
@@ -72,21 +105,64 @@ function toVerdict(reviewer, output) {
|
|
|
72
105
|
: [],
|
|
73
106
|
};
|
|
74
107
|
}
|
|
75
|
-
return
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
108
|
+
return undefined;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* 解析失败的修复指令:只要求重出格式,不重新评审(低 token、聚焦协议修复)。
|
|
112
|
+
* 保留原 prompt(含产物与评审标准)因为子 agent 每次调用都是无状态新会话。
|
|
113
|
+
*/
|
|
114
|
+
function buildRepairPrompt(originalPrompt, lastRaw) {
|
|
115
|
+
return [
|
|
116
|
+
originalPrompt,
|
|
117
|
+
"",
|
|
118
|
+
"=== 重要:你上一次的响应无法解析为 JSON ===",
|
|
119
|
+
"Your previous response could not be parsed.",
|
|
120
|
+
"Return JSON only. Do not include markdown fences or explanation.",
|
|
121
|
+
"",
|
|
122
|
+
"=== 上一次无法解析的输出(供对照,勿原样重复) ===",
|
|
123
|
+
lastRaw.slice(0, 1000),
|
|
124
|
+
"",
|
|
125
|
+
"请重新给出严格 JSON 结论(内容可沿用你上一次的判断,只需修正格式)。",
|
|
126
|
+
].join("\n");
|
|
81
127
|
}
|
|
82
|
-
/**
|
|
128
|
+
/**
|
|
129
|
+
* 语义质量验证:N 个 reviewer 并行评审,全员 pass 才通过。
|
|
130
|
+
* 语义结果永不抛错;协议失败(解析重试耗尽)抛 ReviewerProtocolError——
|
|
131
|
+
* 那不是评审结论,是运维事故:产物未被否定,可安全 resume 重试 verify。
|
|
132
|
+
*/
|
|
83
133
|
export async function verify(artifact, options) {
|
|
84
134
|
const reviewers = Math.max(1, Math.floor(options?.reviewers ?? 1));
|
|
85
135
|
const label = options?.label ?? "semantic verify";
|
|
136
|
+
const attempts = Math.max(1, Math.floor(options?.reviewerProtocol?.attempts ?? 2));
|
|
86
137
|
phase(`Verify(${label}, ${reviewers} reviewer${reviewers > 1 ? "s" : ""})`);
|
|
87
138
|
const text = artifactToText(artifact);
|
|
88
|
-
|
|
89
|
-
const
|
|
139
|
+
// 单 reviewer:仅解析失败局部重试(修复格式,不重新评审);语义结论不重试
|
|
140
|
+
const runReviewer = async (no) => {
|
|
141
|
+
const basePrompt = buildReviewerPrompt(text, no, reviewers, options?.criteria);
|
|
142
|
+
let lastRaw = "";
|
|
143
|
+
for (let attempt = 1; attempt <= attempts; attempt++) {
|
|
144
|
+
const result = await agent(attempt === 1 ? basePrompt : buildRepairPrompt(basePrompt, lastRaw));
|
|
145
|
+
lastRaw = result.output;
|
|
146
|
+
const verdict = toVerdict(no, result.output);
|
|
147
|
+
if (verdict)
|
|
148
|
+
return { status: "reviewed", verdict };
|
|
149
|
+
}
|
|
150
|
+
return { status: "invalid-response", reviewer: no, attempts, lastRaw };
|
|
151
|
+
};
|
|
152
|
+
// 协议失败以哨兵值穿透 parallel(避免被 WorkflowParallelError 包装),在外层统一抛
|
|
153
|
+
const outcomes = await parallel(Array.from({ length: reviewers }, (_, i) => () => runReviewer(i + 1)));
|
|
154
|
+
const protocolFailure = outcomes.find((o) => o.status === "invalid-response");
|
|
155
|
+
if (protocolFailure) {
|
|
156
|
+
emitEvent({
|
|
157
|
+
type: "verify.protocol_failed",
|
|
158
|
+
label,
|
|
159
|
+
reviewer: protocolFailure.reviewer,
|
|
160
|
+
attempts: protocolFailure.attempts,
|
|
161
|
+
lastRaw: protocolFailure.lastRaw.slice(0, 200),
|
|
162
|
+
});
|
|
163
|
+
throw new ReviewerProtocolError(label, protocolFailure.reviewer, protocolFailure.attempts, protocolFailure.lastRaw);
|
|
164
|
+
}
|
|
165
|
+
const verdicts = outcomes.map((o) => o.verdict);
|
|
90
166
|
const passed = verdicts.every((v) => v.verdict === "pass");
|
|
91
167
|
console.log(`[agentic-workflow] verify ${passed ? "ok" : "FAIL"}: ${label} ` +
|
|
92
168
|
`(${verdicts.filter((v) => v.verdict === "pass").length}/${verdicts.length} pass)`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../../src/quality/verify.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../../src/quality/verify.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* string-case —— 字符串命名格式转换(kebab-case)
|
|
3
|
+
*
|
|
4
|
+
* 纯函数、无副作用、无依赖:
|
|
5
|
+
* 以空白、下划线、连字符作为分隔符分词,每个词转小写后用单个 `-` 连接;
|
|
6
|
+
* 首尾分隔符与连续分隔符自动归一,空串输入返回空串。
|
|
7
|
+
*/
|
|
8
|
+
export function kebabCase(s) {
|
|
9
|
+
return s
|
|
10
|
+
.split(/[\s_-]+/)
|
|
11
|
+
.filter(Boolean)
|
|
12
|
+
.map((t) => t.toLowerCase())
|
|
13
|
+
.join("-");
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=string-case.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"string-case.js","sourceRoot":"","sources":["../../src/utils/string-case.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,UAAU,SAAS,CAAC,CAAS;IACjC,OAAO,CAAC;SACL,KAAK,CAAC,SAAS,CAAC;SAChB,MAAM,CAAC,OAAO,CAAC;SACf,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;SAC3B,IAAI,CAAC,GAAG,CAAC,CAAA;AACd,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* titlecase —— 按空白分词的标题大小写转换
|
|
3
|
+
*
|
|
4
|
+
* 纯函数、无副作用、无依赖:
|
|
5
|
+
* 每个词首字母大写、其余小写;空白分隔符(含多个连续空格/制表符)原样保留。
|
|
6
|
+
*/
|
|
7
|
+
export function titlecase(s) {
|
|
8
|
+
return s
|
|
9
|
+
.split(/(\s+)/)
|
|
10
|
+
.map((token) => /^\s+$/.test(token) || token === ""
|
|
11
|
+
? token
|
|
12
|
+
: token.charAt(0).toUpperCase() + token.slice(1).toLowerCase())
|
|
13
|
+
.join("");
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=titlecase.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"titlecase.js","sourceRoot":"","sources":["../../src/utils/titlecase.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,UAAU,SAAS,CAAC,CAAS;IACjC,OAAO,CAAC;SACL,KAAK,CAAC,OAAO,CAAC;SACd,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACb,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,KAAK,EAAE;QACjC,CAAC,CAAC,KAAK;QACP,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CACjE;SACA,IAAI,CAAC,EAAE,CAAC,CAAA;AACb,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* feature-development workflow —— v0.3.x Adoption 招牌 Demo(功能实现链)
|
|
3
|
+
*
|
|
4
|
+
* 链路:需求 -> 分析 -> 实现(隔离 worktree)-> 确定性 check(失败自动修复重试)
|
|
5
|
+
* -> commit 固化 -> 语义 verify(reviewer 审查真实 diff)-> 人工审批
|
|
6
|
+
*
|
|
7
|
+
* 一眼展示「workflow > 单 agent」的差异点:
|
|
8
|
+
* 确定性验证(check)/失败恢复(修复回路 + journalled step + resume)/
|
|
9
|
+
* 语义审查(verify)/人工决策(checkpoint)/可观测(journal/trace/metrics)。
|
|
10
|
+
*
|
|
11
|
+
* 产物固化设计(关键):
|
|
12
|
+
* - 实现以 commit 落在 agw/<runId> 分支上;worktree 按 cleanup 策略清理后
|
|
13
|
+
* 分支保留,交付物不随 worktree 消失(v1 回流方式 = 人工 merge/cherry-pick)。
|
|
14
|
+
* - commit 命令幂等(无暂存变更时跳过提交):check 步骤崩溃后 resume 重跑
|
|
15
|
+
* 不会因「nothing to commit」卡死。
|
|
16
|
+
*
|
|
17
|
+
* 前置要求:isolation(git-worktree)——无隔离时 fail-fast 并给出配置指引。
|
|
18
|
+
*/
|
|
19
|
+
import type { WorkflowDefinition } from "../registry/definition.js";
|
|
20
|
+
import { type ReviewVerdict } from "../quality/verify.js";
|
|
21
|
+
export interface FeatureDevelopmentArgs {
|
|
22
|
+
/** 功能需求(即 feature request 文本) */
|
|
23
|
+
topic: string;
|
|
24
|
+
/** check 命令(在 worktree 根执行;默认安装依赖 + typecheck + test) */
|
|
25
|
+
checkCommand?: string;
|
|
26
|
+
/** reviewer 数量,默认 2 */
|
|
27
|
+
reviewers?: number;
|
|
28
|
+
/**
|
|
29
|
+
* 保留锁文件变更(默认 false):check 命令(npm install 等)可能重写
|
|
30
|
+
* package-lock.json 等锁文件,默认在固化前恢复该噪声(五连坑坑 1);
|
|
31
|
+
* 需求本身涉及依赖变更时置 true。
|
|
32
|
+
*/
|
|
33
|
+
keepLockfileChanges?: boolean;
|
|
34
|
+
}
|
|
35
|
+
/** 链路累积状态:每步返回 {...prev, 新字段},journal 逐步落盘(resume 依赖) */
|
|
36
|
+
export interface FeatureDevState {
|
|
37
|
+
baseSha?: string;
|
|
38
|
+
plan?: string;
|
|
39
|
+
implementation?: string;
|
|
40
|
+
checkLabel?: string;
|
|
41
|
+
checkOk?: boolean;
|
|
42
|
+
fixRounds?: number;
|
|
43
|
+
branch?: string;
|
|
44
|
+
commitSha?: string;
|
|
45
|
+
diffStat?: string;
|
|
46
|
+
verdicts?: ReviewVerdict[];
|
|
47
|
+
approved?: boolean;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* 默认 check 命令:装依赖(worktree 无 node_modules)-> typecheck(若有脚本)
|
|
51
|
+
* -> test(若有脚本)。--if-present 使默认值对任意 npm 项目安全。
|
|
52
|
+
*/
|
|
53
|
+
export declare const DEFAULT_FEATURE_CHECK_COMMAND: string;
|
|
54
|
+
export declare function featureDevelopmentWorkflow(hostOptions?: {
|
|
55
|
+
checkCommand?: string;
|
|
56
|
+
reviewers?: number;
|
|
57
|
+
}): WorkflowDefinition<FeatureDevelopmentArgs, {
|
|
58
|
+
output: string;
|
|
59
|
+
}>;
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* feature-development workflow —— v0.3.x Adoption 招牌 Demo(功能实现链)
|
|
3
|
+
*
|
|
4
|
+
* 链路:需求 -> 分析 -> 实现(隔离 worktree)-> 确定性 check(失败自动修复重试)
|
|
5
|
+
* -> commit 固化 -> 语义 verify(reviewer 审查真实 diff)-> 人工审批
|
|
6
|
+
*
|
|
7
|
+
* 一眼展示「workflow > 单 agent」的差异点:
|
|
8
|
+
* 确定性验证(check)/失败恢复(修复回路 + journalled step + resume)/
|
|
9
|
+
* 语义审查(verify)/人工决策(checkpoint)/可观测(journal/trace/metrics)。
|
|
10
|
+
*
|
|
11
|
+
* 产物固化设计(关键):
|
|
12
|
+
* - 实现以 commit 落在 agw/<runId> 分支上;worktree 按 cleanup 策略清理后
|
|
13
|
+
* 分支保留,交付物不随 worktree 消失(v1 回流方式 = 人工 merge/cherry-pick)。
|
|
14
|
+
* - commit 命令幂等(无暂存变更时跳过提交):check 步骤崩溃后 resume 重跑
|
|
15
|
+
* 不会因「nothing to commit」卡死。
|
|
16
|
+
*
|
|
17
|
+
* 前置要求:isolation(git-worktree)——无隔离时 fail-fast 并给出配置指引。
|
|
18
|
+
*/
|
|
19
|
+
import { observeWorkflow } from "../observability/observe.js";
|
|
20
|
+
import { phase } from "../workflow/phase.js";
|
|
21
|
+
import { agent } from "../workflow/agent.js";
|
|
22
|
+
import { retry } from "../workflow/retry.js";
|
|
23
|
+
import { commandSuccess } from "../quality/predicates.js";
|
|
24
|
+
import { assertVerify } from "../quality/verify.js";
|
|
25
|
+
import { checkpoint } from "../quality/checkpoint.js";
|
|
26
|
+
import { getCommandRunner } from "../runtime/command.js";
|
|
27
|
+
/**
|
|
28
|
+
* 默认 check 命令:装依赖(worktree 无 node_modules)-> typecheck(若有脚本)
|
|
29
|
+
* -> test(若有脚本)。--if-present 使默认值对任意 npm 项目安全。
|
|
30
|
+
*/
|
|
31
|
+
export const DEFAULT_FEATURE_CHECK_COMMAND = "npm install --silent --no-audit --no-fund && " +
|
|
32
|
+
"npm run typecheck --if-present && npm test --if-present";
|
|
33
|
+
/** check 命令超时(npm install + 全量测试的保守上限) */
|
|
34
|
+
const CHECK_TIMEOUT_MS = 900_000;
|
|
35
|
+
/** check 失败后的修复回路轮数(fix agent + 复检) */
|
|
36
|
+
const MAX_FIX_ROUNDS = 2;
|
|
37
|
+
/** 提供给 reviewer 的 diff 文本上限(超出截断) */
|
|
38
|
+
const MAX_DIFF_CHARS = 24_000;
|
|
39
|
+
/** 在 workspace 内执行 git 并返回结果(stdout 供调用方解析) */
|
|
40
|
+
function git(root, gitArgs) {
|
|
41
|
+
return getCommandRunner().run(`git ${gitArgs}`, { cwd: root });
|
|
42
|
+
}
|
|
43
|
+
/** commit 信息安全化:剔除 shell 元字符,截断长度 */
|
|
44
|
+
function safeCommitSubject(topic) {
|
|
45
|
+
return topic.replace(/[`'"\\\n$;]/g, " ").slice(0, 100);
|
|
46
|
+
}
|
|
47
|
+
export function featureDevelopmentWorkflow(hostOptions) {
|
|
48
|
+
return {
|
|
49
|
+
id: "feature-development",
|
|
50
|
+
version: "1.1.0",
|
|
51
|
+
description: "需求分析 -> 隔离 worktree 实现 -> 确定性 check(失败自动修复重试)-> " +
|
|
52
|
+
"reviewer 审查真实 diff -> 人工审批;产物固化为 agw/<runId> 分支 commit。" +
|
|
53
|
+
"需启用 isolation(git-worktree)",
|
|
54
|
+
argsSchema: {
|
|
55
|
+
type: "object",
|
|
56
|
+
properties: {
|
|
57
|
+
topic: { type: "string", description: "功能需求描述(feature request)" },
|
|
58
|
+
checkCommand: {
|
|
59
|
+
type: "string",
|
|
60
|
+
description: "确定性检查命令(在 worktree 根执行,默认 npm install + typecheck + test)",
|
|
61
|
+
},
|
|
62
|
+
reviewers: { type: "integer", description: "reviewer 数量(默认 2)" },
|
|
63
|
+
keepLockfileChanges: {
|
|
64
|
+
type: "boolean",
|
|
65
|
+
description: "保留锁文件变更(默认 false:check 引发的 lockfile 重写会被恢复;需求涉及依赖变更时置 true)",
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
required: ["topic"],
|
|
69
|
+
},
|
|
70
|
+
stepNames: ["analyze", "implement", "check", "verify", "checkpoint"],
|
|
71
|
+
async run(args, ctx) {
|
|
72
|
+
const root = ctx.workspaceRoot;
|
|
73
|
+
if (!root) {
|
|
74
|
+
throw new Error("[feature-development] 该 workflow 需要 workspace 隔离:" +
|
|
75
|
+
'请在插件 options 中配置 "isolation": { "mode": "git-worktree" } 后重试。');
|
|
76
|
+
}
|
|
77
|
+
const checkCommand = args.checkCommand ??
|
|
78
|
+
hostOptions?.checkCommand ??
|
|
79
|
+
DEFAULT_FEATURE_CHECK_COMMAND;
|
|
80
|
+
const reviewers = args.reviewers ?? hostOptions?.reviewers ?? 2;
|
|
81
|
+
return observeWorkflow("feature-development", async () => {
|
|
82
|
+
phase("Develop");
|
|
83
|
+
const state = await ctx.runSteps([
|
|
84
|
+
// 1. 分析:读取仓库(隔离副本),产出实现计划
|
|
85
|
+
async () => {
|
|
86
|
+
const head = await git(root, "rev-parse HEAD");
|
|
87
|
+
if (head.code !== 0 || !head.stdout.trim()) {
|
|
88
|
+
throw new Error("[feature-development] workspace 不是可用的 git 仓库" +
|
|
89
|
+
"(isolation.mode 应为 git-worktree)");
|
|
90
|
+
}
|
|
91
|
+
const plan = await agent("你是资深工程师。当前工作目录是仓库的隔离副本," +
|
|
92
|
+
"可以自由读取文件、探索结构,但不要修改任何文件。\n" +
|
|
93
|
+
`需求:${args.topic}\n` +
|
|
94
|
+
"请给出简明实现计划:改动文件清单(新增/修改)、" +
|
|
95
|
+
"每个文件的职责、测试计划(测试文件路径 + 覆盖场景)。\n" +
|
|
96
|
+
"只输出计划文本;禁止调用 workflow / workflow_metrics 工具。");
|
|
97
|
+
return { baseSha: head.stdout.trim(), plan: plan.output };
|
|
98
|
+
},
|
|
99
|
+
// 2. 实现:agent 在 worktree 内按计划编码(cwd 已绑定 workspace 根)
|
|
100
|
+
async (prev) => {
|
|
101
|
+
const result = await agent("按照以下实现计划,在当前工作目录(仓库隔离副本)中完成编码:\n\n" +
|
|
102
|
+
`${prev?.plan ?? ""}\n\n要求:\n` +
|
|
103
|
+
"- 严格按计划创建/修改文件,并补齐计划中的测试文件\n" +
|
|
104
|
+
"- 不要执行 npm install / npm test / git commit" +
|
|
105
|
+
"(由 workflow 的后续步骤统一负责)\n" +
|
|
106
|
+
"- 完成后只回复:done + 变更文件清单(每行一个路径)\n" +
|
|
107
|
+
"禁止调用 workflow / workflow_metrics 工具。");
|
|
108
|
+
return { ...prev, implementation: result.output };
|
|
109
|
+
},
|
|
110
|
+
// 3. 确定性 check:命令真实执行于 worktree 根;
|
|
111
|
+
// 失败 -> 修复回路(fix agent + 复检,有界)-> 通过后 commit 固化(幂等)
|
|
112
|
+
async (prev) => {
|
|
113
|
+
const label = `check: ${checkCommand} (in workspace)`;
|
|
114
|
+
const checkOnce = () => commandSuccess(checkCommand, {
|
|
115
|
+
cwd: root,
|
|
116
|
+
timeoutMs: CHECK_TIMEOUT_MS,
|
|
117
|
+
});
|
|
118
|
+
let checkOk = await checkOnce();
|
|
119
|
+
let fixRounds = 0;
|
|
120
|
+
if (!checkOk) {
|
|
121
|
+
await retry(async () => {
|
|
122
|
+
fixRounds += 1;
|
|
123
|
+
await agent("当前工作目录中的实现未通过确定性检查:\n" +
|
|
124
|
+
`${checkCommand}\n` +
|
|
125
|
+
"请修复问题使该命令可以通过(可读取文件、修改代码与测试;" +
|
|
126
|
+
"不要执行 npm install / git commit,修复后由 workflow 复检)。" +
|
|
127
|
+
"只回复修复摘要;禁止调用 workflow / workflow_metrics 工具。");
|
|
128
|
+
const ok = await checkOnce();
|
|
129
|
+
if (!ok)
|
|
130
|
+
throw new Error(`check 仍未通过:${checkCommand}`);
|
|
131
|
+
}, { attempts: MAX_FIX_ROUNDS, delayMs: 5_000, label: "feature-check" });
|
|
132
|
+
checkOk = true;
|
|
133
|
+
}
|
|
134
|
+
// 五连坑坑 1 修复:check 命令(npm install 等)可能重写锁文件,
|
|
135
|
+
// 固化前恢复该噪声;需求本身涉及依赖变更时经 keepLockfileChanges 保留
|
|
136
|
+
if (!args.keepLockfileChanges) {
|
|
137
|
+
await getCommandRunner().run("for f in package-lock.json npm-shrinkwrap.json pnpm-lock.yaml yarn.lock bun.lockb; " +
|
|
138
|
+
'do git checkout -- "$f" 2>/dev/null || true; done', { cwd: root });
|
|
139
|
+
}
|
|
140
|
+
// 产物固化为 commit:幂等(无暂存变更时跳过),resume 重跑安全
|
|
141
|
+
const commitScript = "git add -A && " +
|
|
142
|
+
`(git diff --cached --quiet || git commit -m 'agentic-workflow(feature-development): ${safeCommitSubject(args.topic)}')`;
|
|
143
|
+
const commit = await getCommandRunner().run(commitScript, { cwd: root });
|
|
144
|
+
if (commit.code !== 0) {
|
|
145
|
+
throw new Error(`[feature-development] commit 失败: ${commit.stderr}`);
|
|
146
|
+
}
|
|
147
|
+
const [sha, branch, stat] = await Promise.all([
|
|
148
|
+
git(root, "rev-parse HEAD"),
|
|
149
|
+
git(root, "rev-parse --abbrev-ref HEAD"),
|
|
150
|
+
git(root, `diff --stat ${prev?.baseSha ?? "HEAD"}..HEAD`),
|
|
151
|
+
]);
|
|
152
|
+
return {
|
|
153
|
+
...prev,
|
|
154
|
+
checkLabel: label,
|
|
155
|
+
checkOk,
|
|
156
|
+
fixRounds,
|
|
157
|
+
branch: branch.stdout.trim(),
|
|
158
|
+
commitSha: sha.stdout.trim(),
|
|
159
|
+
diffStat: stat.stdout.trim(),
|
|
160
|
+
};
|
|
161
|
+
},
|
|
162
|
+
// 4. 语义 verify:reviewer 并行审查「真实 diff」(非 agent 自述)
|
|
163
|
+
// 五连坑坑 4 修复:diffStat/commitSha 与 diff 同源现算,
|
|
164
|
+
// 不引用 journal 中 check 步骤的缓存值(外部 amend 等修正后仍强一致)
|
|
165
|
+
async (prev) => {
|
|
166
|
+
const baseSha = prev?.baseSha;
|
|
167
|
+
if (!baseSha) {
|
|
168
|
+
throw new Error("[feature-development] verify: 缺少 baseSha(analyze 状态丢失)");
|
|
169
|
+
}
|
|
170
|
+
const [diff, stat, sha] = await Promise.all([
|
|
171
|
+
git(root, `diff ${baseSha}..HEAD`),
|
|
172
|
+
git(root, `diff --stat ${baseSha}..HEAD`),
|
|
173
|
+
git(root, "rev-parse HEAD"),
|
|
174
|
+
]);
|
|
175
|
+
const diffText = diff.stdout.length > MAX_DIFF_CHARS
|
|
176
|
+
? diff.stdout.slice(0, MAX_DIFF_CHARS) + "\n…(diff 已截断)"
|
|
177
|
+
: diff.stdout;
|
|
178
|
+
const freshDiffStat = stat.stdout.trim();
|
|
179
|
+
const artifactText = [
|
|
180
|
+
`需求:${args.topic}`,
|
|
181
|
+
"",
|
|
182
|
+
"## 实现计划",
|
|
183
|
+
prev?.plan ?? "",
|
|
184
|
+
"",
|
|
185
|
+
"## 变更统计",
|
|
186
|
+
freshDiffStat,
|
|
187
|
+
"",
|
|
188
|
+
"## 完整 diff",
|
|
189
|
+
"```diff",
|
|
190
|
+
diffText,
|
|
191
|
+
"```",
|
|
192
|
+
].join("\n");
|
|
193
|
+
const result = await assertVerify(artifactText, {
|
|
194
|
+
reviewers,
|
|
195
|
+
label: `verify: ${args.topic}`.slice(0, 80),
|
|
196
|
+
criteria: "改动与需求相符、实现正确、包含覆盖关键行为的测试、" +
|
|
197
|
+
"未引入明显缺陷或破坏现有代码",
|
|
198
|
+
});
|
|
199
|
+
return {
|
|
200
|
+
...prev,
|
|
201
|
+
diffStat: freshDiffStat,
|
|
202
|
+
commitSha: sha.stdout.trim(),
|
|
203
|
+
verdicts: result.verdicts,
|
|
204
|
+
};
|
|
205
|
+
},
|
|
206
|
+
// 5. 人工审批:决定实现是否被接受
|
|
207
|
+
async (prev) => {
|
|
208
|
+
const verdicts = prev?.verdicts ?? [];
|
|
209
|
+
const passed = verdicts.filter((v) => v.verdict === "pass").length;
|
|
210
|
+
await checkpoint(`实现已通过确定性检查` +
|
|
211
|
+
`${(prev?.fixRounds ?? 0) > 0 ? `(含 ${prev?.fixRounds} 轮自动修复)` : ""}` +
|
|
212
|
+
`与 ${passed}/${verdicts.length} reviewer 审查,` +
|
|
213
|
+
`已提交到分支 ${prev?.branch}。是否接受该实现?`, { label: "accept-implementation" });
|
|
214
|
+
return { ...prev, approved: true };
|
|
215
|
+
},
|
|
216
|
+
], { stepNames: ["analyze", "implement", "check", "verify", "checkpoint"] });
|
|
217
|
+
phase("Done");
|
|
218
|
+
const verdicts = state?.verdicts ?? [];
|
|
219
|
+
const passed = verdicts.filter((v) => v.verdict === "pass").length;
|
|
220
|
+
const fixRounds = state?.fixRounds ?? 0;
|
|
221
|
+
const output = [
|
|
222
|
+
`# Feature Development 报告:${args.topic}`,
|
|
223
|
+
"",
|
|
224
|
+
"1. 分析:实现计划已生成" + `(${(state?.plan ?? "").length} 字符)`,
|
|
225
|
+
"2. 实现:agent 已在隔离 worktree 完成编码",
|
|
226
|
+
`3. 确定性检查 ${state?.checkOk ? "通过" : "失败"}:${state?.checkLabel ?? ""}` +
|
|
227
|
+
`${fixRounds > 0 ? `(经 ${fixRounds} 轮自动修复)` : ""}`,
|
|
228
|
+
`4. 语义验证:${passed}/${verdicts.length} reviewer 通过`,
|
|
229
|
+
`5. 审批:${state?.approved ? "已批准" : "未批准"}`,
|
|
230
|
+
"",
|
|
231
|
+
"## 产物(已固化为分支 commit)",
|
|
232
|
+
`- 分支:${state?.branch ?? "(未知)"}`,
|
|
233
|
+
`- commit:${(state?.commitSha ?? "").slice(0, 8)}`,
|
|
234
|
+
"- 变更统计:",
|
|
235
|
+
...(state?.diffStat ?? "")
|
|
236
|
+
.split("\n")
|
|
237
|
+
.filter(Boolean)
|
|
238
|
+
.map((line) => ` ${line}`),
|
|
239
|
+
`- worktree:${root}(按 cleanup 策略处理;分支保留)`,
|
|
240
|
+
"",
|
|
241
|
+
"回流方式:对目标仓库 `git merge` / `git cherry-pick` 该分支即可引入实现。",
|
|
242
|
+
].join("\n");
|
|
243
|
+
return { output };
|
|
244
|
+
}, { topic: args.topic, checkCommand, reviewers });
|
|
245
|
+
},
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
//# sourceMappingURL=feature-development.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feature-development.js","sourceRoot":"","sources":["../../src/workflows/feature-development.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* InPlaceWorkspaceProvider —— 无隔离模式的默认工作区(P3 Blocker 修复)
|
|
3
|
+
*
|
|
4
|
+
* 背景:workspaceRoot 之前只在配置 git-worktree 隔离时才存在;无隔离时
|
|
5
|
+
* 流程落到 process.cwd()——在 OpenCode 托管进程里 cwd **不是**项目目录
|
|
6
|
+
* (长驻 server 场景实测为 HOME),导致 artifact/reliable 等以
|
|
7
|
+
* 「workspace 根」为前提的流程假失败(文件写对位置、check 查错位置)。
|
|
8
|
+
*
|
|
9
|
+
* 语义:
|
|
10
|
+
* - create():root = 项目目录(原地,不创建任何东西)
|
|
11
|
+
* - dispose():必须 no-op——原地工作区就是用户的项目目录,绝不能删
|
|
12
|
+
* - attach():resume 时回到 journal 记录的原目录;目录消失必须抛错
|
|
13
|
+
* (绝不静默重建,与 worktree 纪律一致)
|
|
14
|
+
*/
|
|
15
|
+
import type { WorkspaceHandle, WorkspaceIdentity, WorkspaceProvider } from "./provider.js";
|
|
16
|
+
export interface InPlaceWorkspaceProviderOptions {
|
|
17
|
+
/** 项目目录(workspaceRoot 解析到这里) */
|
|
18
|
+
startDir: string;
|
|
19
|
+
}
|
|
20
|
+
export declare class InPlaceWorkspaceProvider implements WorkspaceProvider {
|
|
21
|
+
readonly kind = "in-place";
|
|
22
|
+
private readonly startDir;
|
|
23
|
+
constructor(options: InPlaceWorkspaceProviderOptions);
|
|
24
|
+
create(): Promise<WorkspaceHandle>;
|
|
25
|
+
attach(identity: WorkspaceIdentity): Promise<WorkspaceHandle>;
|
|
26
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* InPlaceWorkspaceProvider —— 无隔离模式的默认工作区(P3 Blocker 修复)
|
|
3
|
+
*
|
|
4
|
+
* 背景:workspaceRoot 之前只在配置 git-worktree 隔离时才存在;无隔离时
|
|
5
|
+
* 流程落到 process.cwd()——在 OpenCode 托管进程里 cwd **不是**项目目录
|
|
6
|
+
* (长驻 server 场景实测为 HOME),导致 artifact/reliable 等以
|
|
7
|
+
* 「workspace 根」为前提的流程假失败(文件写对位置、check 查错位置)。
|
|
8
|
+
*
|
|
9
|
+
* 语义:
|
|
10
|
+
* - create():root = 项目目录(原地,不创建任何东西)
|
|
11
|
+
* - dispose():必须 no-op——原地工作区就是用户的项目目录,绝不能删
|
|
12
|
+
* - attach():resume 时回到 journal 记录的原目录;目录消失必须抛错
|
|
13
|
+
* (绝不静默重建,与 worktree 纪律一致)
|
|
14
|
+
*/
|
|
15
|
+
import { existsSync } from "node:fs";
|
|
16
|
+
import path from "node:path";
|
|
17
|
+
export class InPlaceWorkspaceProvider {
|
|
18
|
+
kind = "in-place";
|
|
19
|
+
startDir;
|
|
20
|
+
constructor(options) {
|
|
21
|
+
this.startDir = options.startDir;
|
|
22
|
+
}
|
|
23
|
+
async create() {
|
|
24
|
+
const root = path.resolve(this.startDir);
|
|
25
|
+
return {
|
|
26
|
+
root,
|
|
27
|
+
identity: { provider: this.kind, path: root },
|
|
28
|
+
dispose: async () => {
|
|
29
|
+
// 原地工作区 = 用户项目目录本身:清理永远是 no-op
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
async attach(identity) {
|
|
34
|
+
if (identity.provider !== this.kind) {
|
|
35
|
+
throw new Error(`in-place provider cannot attach a "${identity.provider}" workspace`);
|
|
36
|
+
}
|
|
37
|
+
if (!existsSync(identity.path)) {
|
|
38
|
+
throw new Error(`in-place workspace no longer exists: ${identity.path} ` +
|
|
39
|
+
"(resume requires the original project directory)");
|
|
40
|
+
}
|
|
41
|
+
return {
|
|
42
|
+
root: identity.path,
|
|
43
|
+
identity,
|
|
44
|
+
dispose: async () => { },
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=in-place.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"in-place.js","sourceRoot":"","sources":["../../src/workspace/in-place.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACpC,OAAO,IAAI,MAAM,WAAW,CAAA;AAY5B,MAAM,OAAO,wBAAwB;IAC1B,IAAI,GAAG,UAAU,CAAA;IAET,QAAQ,CAAQ;IAEjC,YAAY,OAAwC;QAClD,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAA;IAClC,CAAC;IAED,KAAK,CAAC,MAAM;QACV,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QACxC,OAAO;YACL,IAAI;YACJ,QAAQ,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE;YAC7C,OAAO,EAAE,KAAK,IAAI,EAAE;gBAClB,+BAA+B;YACjC,CAAC;SACF,CAAA;IACH,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,QAA2B;QACtC,IAAI,QAAQ,CAAC,QAAQ,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;YACpC,MAAM,IAAI,KAAK,CACb,sCAAsC,QAAQ,CAAC,QAAQ,aAAa,CACrE,CAAA;QACH,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CACb,wCAAwC,QAAQ,CAAC,IAAI,GAAG;gBACtD,kDAAkD,CACrD,CAAA;QACH,CAAC;QACD,OAAO;YACL,IAAI,EAAE,QAAQ,CAAC,IAAI;YACnB,QAAQ;YACR,OAAO,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;SACxB,CAAA;IACH,CAAC;CACF"}
|
|
@@ -3,4 +3,5 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export type { WorkspaceHandle, WorkspaceIdentity, WorkspaceOptions, WorkspaceProvider, CleanupPolicy, } from "./provider.js";
|
|
5
5
|
export { GitWorktreeProvider, type GitWorktreeProviderOptions } from "./git-worktree.js";
|
|
6
|
+
export { InPlaceWorkspaceProvider, type InPlaceWorkspaceProviderOptions, } from "./in-place.js";
|
|
6
7
|
export { currentWorkspace, setCurrentWorkspace } from "./ambient.js";
|
package/dist/workspace/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/workspace/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AASH,OAAO,EAAE,mBAAmB,EAAmC,MAAM,mBAAmB,CAAA;AACxF,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/workspace/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AASH,OAAO,EAAE,mBAAmB,EAAmC,MAAM,mBAAmB,CAAA;AACxF,OAAO,EACL,wBAAwB,GAEzB,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mickorz/opencode-agentic-workflow",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Durable Agentic Workflow Runtime for OpenCode V2: journal & resume, version registry, tracing, token/cost metrics, git worktree isolation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|