@mickorz/opencode-agentic-workflow 0.3.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.
Files changed (144) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +406 -0
  3. package/dist/metrics/collector.d.ts +98 -0
  4. package/dist/metrics/collector.js +246 -0
  5. package/dist/metrics/collector.js.map +1 -0
  6. package/dist/observability/events.d.ts +99 -0
  7. package/dist/observability/events.js +55 -0
  8. package/dist/observability/events.js.map +1 -0
  9. package/dist/observability/observe.d.ts +7 -0
  10. package/dist/observability/observe.js +29 -0
  11. package/dist/observability/observe.js.map +1 -0
  12. package/dist/observability/trace.d.ts +26 -0
  13. package/dist/observability/trace.js +52 -0
  14. package/dist/observability/trace.js.map +1 -0
  15. package/dist/plugin/checkpoint-rpc.d.ts +74 -0
  16. package/dist/plugin/checkpoint-rpc.js +73 -0
  17. package/dist/plugin/checkpoint-rpc.js.map +1 -0
  18. package/dist/plugin/index.d.ts +24 -0
  19. package/dist/plugin/index.js +271 -0
  20. package/dist/plugin/index.js.map +1 -0
  21. package/dist/plugin/interactive-checkpoint-gate.d.ts +35 -0
  22. package/dist/plugin/interactive-checkpoint-gate.js +86 -0
  23. package/dist/plugin/interactive-checkpoint-gate.js.map +1 -0
  24. package/dist/plugin/opencode-v2-executor.d.ts +55 -0
  25. package/dist/plugin/opencode-v2-executor.js +92 -0
  26. package/dist/plugin/opencode-v2-executor.js.map +1 -0
  27. package/dist/plugin/policy-checkpoint-gate.d.ts +18 -0
  28. package/dist/plugin/policy-checkpoint-gate.js +27 -0
  29. package/dist/plugin/policy-checkpoint-gate.js.map +1 -0
  30. package/dist/plugin/price-table.d.ts +46 -0
  31. package/dist/plugin/price-table.js +44 -0
  32. package/dist/plugin/price-table.js.map +1 -0
  33. package/dist/plugin/tui.d.ts +12 -0
  34. package/dist/plugin/tui.js +53 -0
  35. package/dist/plugin/tui.js.map +1 -0
  36. package/dist/quality/check.d.ts +30 -0
  37. package/dist/quality/check.js +51 -0
  38. package/dist/quality/check.js.map +1 -0
  39. package/dist/quality/checkpoint.d.ts +44 -0
  40. package/dist/quality/checkpoint.js +55 -0
  41. package/dist/quality/checkpoint.js.map +1 -0
  42. package/dist/quality/json.d.ts +10 -0
  43. package/dist/quality/json.js +31 -0
  44. package/dist/quality/json.js.map +1 -0
  45. package/dist/quality/predicates.d.ts +17 -0
  46. package/dist/quality/predicates.js +44 -0
  47. package/dist/quality/predicates.js.map +1 -0
  48. package/dist/quality/verify.d.ts +50 -0
  49. package/dist/quality/verify.js +110 -0
  50. package/dist/quality/verify.js.map +1 -0
  51. package/dist/registry/definition.d.ts +66 -0
  52. package/dist/registry/definition.js +19 -0
  53. package/dist/registry/definition.js.map +1 -0
  54. package/dist/registry/errors.d.ts +31 -0
  55. package/dist/registry/errors.js +48 -0
  56. package/dist/registry/errors.js.map +1 -0
  57. package/dist/registry/index.d.ts +9 -0
  58. package/dist/registry/index.js +9 -0
  59. package/dist/registry/index.js.map +1 -0
  60. package/dist/registry/registry.d.ts +45 -0
  61. package/dist/registry/registry.js +117 -0
  62. package/dist/registry/registry.js.map +1 -0
  63. package/dist/registry/runner.d.ts +56 -0
  64. package/dist/registry/runner.js +199 -0
  65. package/dist/registry/runner.js.map +1 -0
  66. package/dist/registry/schema.d.ts +18 -0
  67. package/dist/registry/schema.js +73 -0
  68. package/dist/registry/schema.js.map +1 -0
  69. package/dist/runtime/command.d.ts +38 -0
  70. package/dist/runtime/command.js +61 -0
  71. package/dist/runtime/command.js.map +1 -0
  72. package/dist/runtime/engine.d.ts +17 -0
  73. package/dist/runtime/engine.js +31 -0
  74. package/dist/runtime/engine.js.map +1 -0
  75. package/dist/runtime/errors.d.ts +56 -0
  76. package/dist/runtime/errors.js +88 -0
  77. package/dist/runtime/errors.js.map +1 -0
  78. package/dist/runtime/executor.d.ts +46 -0
  79. package/dist/runtime/executor.js +16 -0
  80. package/dist/runtime/executor.js.map +1 -0
  81. package/dist/runtime/semaphore.d.ts +24 -0
  82. package/dist/runtime/semaphore.js +57 -0
  83. package/dist/runtime/semaphore.js.map +1 -0
  84. package/dist/state/file-store.d.ts +25 -0
  85. package/dist/state/file-store.js +138 -0
  86. package/dist/state/file-store.js.map +1 -0
  87. package/dist/state/journal.d.ts +83 -0
  88. package/dist/state/journal.js +59 -0
  89. package/dist/state/journal.js.map +1 -0
  90. package/dist/state/recorder.d.ts +63 -0
  91. package/dist/state/recorder.js +138 -0
  92. package/dist/state/recorder.js.map +1 -0
  93. package/dist/state/store.d.ts +23 -0
  94. package/dist/state/store.js +14 -0
  95. package/dist/state/store.js.map +1 -0
  96. package/dist/workflow/agent.d.ts +8 -0
  97. package/dist/workflow/agent.js +38 -0
  98. package/dist/workflow/agent.js.map +1 -0
  99. package/dist/workflow/fallback.d.ts +15 -0
  100. package/dist/workflow/fallback.js +32 -0
  101. package/dist/workflow/fallback.js.map +1 -0
  102. package/dist/workflow/parallel.d.ts +14 -0
  103. package/dist/workflow/parallel.js +62 -0
  104. package/dist/workflow/parallel.js.map +1 -0
  105. package/dist/workflow/phase.d.ts +7 -0
  106. package/dist/workflow/phase.js +12 -0
  107. package/dist/workflow/phase.js.map +1 -0
  108. package/dist/workflow/reliable.d.ts +50 -0
  109. package/dist/workflow/reliable.js +92 -0
  110. package/dist/workflow/reliable.js.map +1 -0
  111. package/dist/workflow/retry.d.ts +28 -0
  112. package/dist/workflow/retry.js +53 -0
  113. package/dist/workflow/retry.js.map +1 -0
  114. package/dist/workflow/sequence.d.ts +40 -0
  115. package/dist/workflow/sequence.js +100 -0
  116. package/dist/workflow/sequence.js.map +1 -0
  117. package/dist/workflow/smoke.d.ts +17 -0
  118. package/dist/workflow/smoke.js +38 -0
  119. package/dist/workflow/smoke.js.map +1 -0
  120. package/dist/workflows/artifact.d.ts +24 -0
  121. package/dist/workflows/artifact.js +71 -0
  122. package/dist/workflows/artifact.js.map +1 -0
  123. package/dist/workflows/index.d.ts +19 -0
  124. package/dist/workflows/index.js +40 -0
  125. package/dist/workflows/index.js.map +1 -0
  126. package/dist/workflows/reliable.d.ts +18 -0
  127. package/dist/workflows/reliable.js +32 -0
  128. package/dist/workflows/reliable.js.map +1 -0
  129. package/dist/workflows/smoke.d.ts +13 -0
  130. package/dist/workflows/smoke.js +26 -0
  131. package/dist/workflows/smoke.js.map +1 -0
  132. package/dist/workspace/ambient.d.ts +12 -0
  133. package/dist/workspace/ambient.js +17 -0
  134. package/dist/workspace/ambient.js.map +1 -0
  135. package/dist/workspace/git-worktree.d.ts +29 -0
  136. package/dist/workspace/git-worktree.js +110 -0
  137. package/dist/workspace/git-worktree.js.map +1 -0
  138. package/dist/workspace/index.d.ts +6 -0
  139. package/dist/workspace/index.js +6 -0
  140. package/dist/workspace/index.js.map +1 -0
  141. package/dist/workspace/provider.d.ts +61 -0
  142. package/dist/workspace/provider.js +15 -0
  143. package/dist/workspace/provider.js.map +1 -0
  144. package/package.json +71 -0
@@ -0,0 +1,199 @@
1
+ /**
2
+ * Registry Runner(P2.5 journal 集成)
3
+ *
4
+ * 把 Definition / Registry / Journal / Resume 正式串起来:
5
+ *
6
+ * startWorkflow: registry.resolve(id)[@version] -> args 校验 -> journal 落盘
7
+ * -> definition.run(args, ctx{mode:"start"})
8
+ * -> ctx.runSteps = sequence + journal 记录
9
+ *
10
+ * resumeWorkflow: store.getRun(runId) -> workflow {id, version}
11
+ * -> registry.resolve(id, version) ← 精确版本,绝不取最新
12
+ * -> definition.run(journal.args, ctx{mode:"resume"})
13
+ * -> ctx.runSteps = resumeSequence(跳过 completed 前缀)
14
+ *
15
+ * definition 只感知 ctx.runSteps——start/resume 差异被完全封装;
16
+ * 失败统一抛 WorkflowExecutionError(携带 runId,供工具层提示恢复入口)。
17
+ */
18
+ import { RunJournal } from "../state/recorder.js";
19
+ import { setCurrentWorkspace, } from "../workspace/index.js";
20
+ import { resumeSequence, sequence, } from "../workflow/sequence.js";
21
+ import { WorkflowArgsError, WorkflowExecutionError } from "./errors.js";
22
+ import { validateArgs } from "./schema.js";
23
+ function toOutput(result) {
24
+ if (typeof result === "string")
25
+ return result;
26
+ if (result &&
27
+ typeof result === "object" &&
28
+ typeof result.output === "string") {
29
+ return result.output;
30
+ }
31
+ return JSON.stringify(result) ?? "";
32
+ }
33
+ function createContext(input) {
34
+ return {
35
+ runId: input.runId,
36
+ mode: input.mode,
37
+ // resume 模式的 journal 由 resumeSequence 内部管理(attach/reopen/收口),
38
+ // ctx 不直接暴露,避免双写
39
+ journal: input.mode === "start" ? input.journal : undefined,
40
+ // P2.7:隔离工作区根目录(未启用隔离时为 undefined)
41
+ workspaceRoot: input.workspaceRoot,
42
+ runSteps(steps, options) {
43
+ if (input.mode === "resume" && input.store) {
44
+ return resumeSequence(input.store, input.runId, steps, options);
45
+ }
46
+ return sequence(steps, {
47
+ ...options,
48
+ journal: input.journal,
49
+ });
50
+ },
51
+ };
52
+ }
53
+ /**
54
+ * 无持久化直跑(插件未配置 journalDir 时的兼容路径):
55
+ * 经注册表解析 + args 校验,但不落 journal、不可恢复。
56
+ */
57
+ export async function runWorkflowInline(registry, id, args) {
58
+ const definition = registry.resolve(id);
59
+ const problems = validateArgs(definition.argsSchema, args);
60
+ if (problems.length > 0) {
61
+ throw new WorkflowArgsError(definition.id, problems);
62
+ }
63
+ const result = await definition.run(args, {
64
+ runId: `inline_${Date.now()}`,
65
+ mode: "start",
66
+ runSteps: (steps, options) => sequence(steps, options),
67
+ });
68
+ return { output: toOutput(result) };
69
+ }
70
+ /** 收口辅助:成功路径把仍为 running 的 journal 置 completed(step-less 工作流兜底) */
71
+ async function settleAfterSuccess(store, runId) {
72
+ const journal = await RunJournal.attach(store, runId);
73
+ if (!journal)
74
+ return;
75
+ if (journal.run.status === "running") {
76
+ await journal.complete();
77
+ }
78
+ else if (journal.run.status === "failed") {
79
+ // resume 成功但 definition 未走 runSteps(step-less):failed -> completed
80
+ await journal.reopen();
81
+ await journal.complete();
82
+ }
83
+ }
84
+ async function settleAfterFailure(store, runId, error) {
85
+ const journal = await RunJournal.attach(store, runId);
86
+ if (journal && journal.run.status === "running") {
87
+ await journal.fail(error);
88
+ }
89
+ }
90
+ /**
91
+ * 按策略清理 workspace;清理后清除 journal 中的 workspace 身份
92
+ * (否则已清理的 run 在幂等 resume 时会 attach 一个已删除的目录)。
93
+ * 清理失败只记录——观测/基础设施不能成为主链路故障源。
94
+ */
95
+ async function cleanupWorkspace(store, runId, handle, policy, success) {
96
+ if (!handle)
97
+ return;
98
+ if (policy === "never")
99
+ return;
100
+ if (policy === "on-success" && !success)
101
+ return;
102
+ try {
103
+ await handle.dispose({ force: true });
104
+ const journal = await RunJournal.attach(store, runId);
105
+ await journal?.clearWorkspace();
106
+ }
107
+ catch (error) {
108
+ console.log(`[agentic-workflow] workspace cleanup failed for ${runId}: ` +
109
+ `${error instanceof Error ? error.message : String(error)}`);
110
+ }
111
+ }
112
+ /** 启动新 run(默认最新版本;可用 options.version 精确指定) */
113
+ export async function startWorkflow(registry, store, id, args, options) {
114
+ const definition = registry.resolve(id, options?.version);
115
+ const problems = validateArgs(definition.argsSchema, args);
116
+ if (problems.length > 0) {
117
+ throw new WorkflowArgsError(definition.id, problems);
118
+ }
119
+ const identity = { id: definition.id, version: definition.version };
120
+ const journal = await RunJournal.start(store, {
121
+ workflow: identity,
122
+ args,
123
+ stepNames: definition.stepNames,
124
+ stepCount: definition.stepNames?.length ?? 0,
125
+ });
126
+ const runId = journal.run.runId;
127
+ const cleanupPolicy = options?.workspace?.cleanup ?? "on-success";
128
+ let workspace;
129
+ try {
130
+ // P2.7:创建隔离工作区并把身份落 journal(resume attach 依据)
131
+ if (options?.workspace) {
132
+ workspace = await options.workspace.provider.create(runId, options.workspace.options);
133
+ await journal.setWorkspace(workspace.identity);
134
+ }
135
+ setCurrentWorkspace(workspace);
136
+ try {
137
+ const result = await definition.run(args, createContext({ runId, mode: "start", journal, workspaceRoot: workspace?.root }));
138
+ // 顺序纪律:先收口 journal 再清理 workspace——cleanupWorkspace 会经
139
+ // attach 重读持久化状态并清除 workspace 字段,若 complete() 在其后,
140
+ // 内存 journal 会把已删除的 worktree 身份复活写回(幂等 resume 即坏)
141
+ if (journal.run.status === "running") {
142
+ await journal.complete();
143
+ }
144
+ await cleanupWorkspace(store, runId, workspace, cleanupPolicy, true);
145
+ return { runId, workflow: identity, output: toOutput(result) };
146
+ }
147
+ finally {
148
+ setCurrentWorkspace(undefined);
149
+ }
150
+ }
151
+ catch (error) {
152
+ if (journal.run.status === "running") {
153
+ await journal.fail(error);
154
+ }
155
+ await cleanupWorkspace(store, runId, workspace, cleanupPolicy, false);
156
+ throw new WorkflowExecutionError({ runId, ...identity }, error);
157
+ }
158
+ }
159
+ /**
160
+ * 从 journal 恢复 run:
161
+ * - workflow {id, version} 来自 journal,registry 精确版本解析(找不到即报错并列版本)
162
+ * - args 取 journal 记录(无需调用方重新提供)
163
+ * - journal 记录了 workspace 身份时,**重新附着原工作区**(绝不重建——
164
+ * durable resume = journal 状态 + 文件系统状态同时恢复;缺失即报错)
165
+ * - 已完成的 run 幂等重放(不执行任何步骤,仅重建最终报告)
166
+ */
167
+ export async function resumeWorkflow(registry, store, runId, options) {
168
+ const run = await store.getRun(runId);
169
+ if (!run) {
170
+ throw new Error(`[agentic-workflow] cannot resume: run not found: ${runId}`);
171
+ }
172
+ const identity = run.workflow;
173
+ const definition = registry.resolve(identity.id, identity.version);
174
+ const cleanupPolicy = options?.workspace?.cleanup ?? "on-success";
175
+ let workspace;
176
+ try {
177
+ if (options?.workspace && run.workspace) {
178
+ workspace = await options.workspace.provider.attach(run.workspace);
179
+ }
180
+ setCurrentWorkspace(workspace);
181
+ try {
182
+ const result = await definition.run(run.args, createContext({ runId, mode: "resume", store, workspaceRoot: workspace?.root }));
183
+ // 同 start:先收口 journal(settle),再清理 workspace(clearWorkspace
184
+ // 允许在收口后执行——幂等 resume 依赖清理后字段被清掉)
185
+ await settleAfterSuccess(store, runId);
186
+ await cleanupWorkspace(store, runId, workspace, cleanupPolicy, true);
187
+ return { runId, workflow: identity, output: toOutput(result) };
188
+ }
189
+ finally {
190
+ setCurrentWorkspace(undefined);
191
+ }
192
+ }
193
+ catch (error) {
194
+ await settleAfterFailure(store, runId, error);
195
+ await cleanupWorkspace(store, runId, workspace, cleanupPolicy, false);
196
+ throw new WorkflowExecutionError({ runId, ...identity }, error);
197
+ }
198
+ }
199
+ //# sourceMappingURL=runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/registry/runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Args JSON Schema 子集(P2.5)
3
+ *
4
+ * 项目保持零依赖:不引入 Zod,实现最小 JSON Schema 校验
5
+ * (type/properties/required/enum/items/description,支持嵌套与联合类型)。
6
+ * 该契约同时用于:tool schema 生成、args 校验、未来 TUI 表单 / Hub 展示。
7
+ */
8
+ /** 最小 JSON Schema 子集(声明 args 契约用) */
9
+ export interface ArgsSchema {
10
+ type?: string | string[];
11
+ properties?: Record<string, ArgsSchema>;
12
+ required?: string[];
13
+ enum?: unknown[];
14
+ items?: ArgsSchema;
15
+ description?: string;
16
+ }
17
+ /** args 校验:返回问题列表(空数组 = 合法) */
18
+ export declare function validateArgs(schema: ArgsSchema | undefined, args: unknown): string[];
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Args JSON Schema 子集(P2.5)
3
+ *
4
+ * 项目保持零依赖:不引入 Zod,实现最小 JSON Schema 校验
5
+ * (type/properties/required/enum/items/description,支持嵌套与联合类型)。
6
+ * 该契约同时用于:tool schema 生成、args 校验、未来 TUI 表单 / Hub 展示。
7
+ */
8
+ /** args 校验:返回问题列表(空数组 = 合法) */
9
+ export function validateArgs(schema, args) {
10
+ if (!schema)
11
+ return [];
12
+ return validateValue(schema, args, "args");
13
+ }
14
+ function validateValue(schema, value, path) {
15
+ const problems = [];
16
+ if (schema.type) {
17
+ const expected = Array.isArray(schema.type) ? schema.type : [schema.type];
18
+ if (!expected.some((t) => matchesType(t, value))) {
19
+ problems.push(`${path}: expected type ${expected.join("|")}, got ${typeName(value)}`);
20
+ return problems; // 类型不对,后续检查无意义
21
+ }
22
+ }
23
+ if (schema.enum && !schema.enum.some((candidate) => candidate === value)) {
24
+ problems.push(`${path}: expected one of ${JSON.stringify(schema.enum)}`);
25
+ }
26
+ if (typeof value === "object" && value !== null && schema.properties) {
27
+ const record = value;
28
+ for (const key of schema.required ?? []) {
29
+ if (!(key in record) || record[key] === undefined) {
30
+ problems.push(`${path}: missing required property "${key}"`);
31
+ }
32
+ }
33
+ for (const [key, childSchema] of Object.entries(schema.properties)) {
34
+ if (key in record && record[key] !== undefined) {
35
+ problems.push(...validateValue(childSchema, record[key], `${path}.${key}`));
36
+ }
37
+ }
38
+ }
39
+ if (Array.isArray(value) && schema.items) {
40
+ value.forEach((item, index) => {
41
+ problems.push(...validateValue(schema.items, item, `${path}[${index}]`));
42
+ });
43
+ }
44
+ return problems;
45
+ }
46
+ function matchesType(expected, value) {
47
+ switch (expected) {
48
+ case "string":
49
+ return typeof value === "string";
50
+ case "number":
51
+ return typeof value === "number" && !Number.isNaN(value);
52
+ case "integer":
53
+ return typeof value === "number" && Number.isInteger(value);
54
+ case "boolean":
55
+ return typeof value === "boolean";
56
+ case "array":
57
+ return Array.isArray(value);
58
+ case "object":
59
+ return typeof value === "object" && value !== null && !Array.isArray(value);
60
+ case "null":
61
+ return value === null;
62
+ default:
63
+ return true; // 未知类型名不设限(前向兼容)
64
+ }
65
+ }
66
+ function typeName(value) {
67
+ if (value === null)
68
+ return "null";
69
+ if (Array.isArray(value))
70
+ return "array";
71
+ return typeof value;
72
+ }
73
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/registry/schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * CommandRunner —— 命令执行抽象(Workflow Core 内的宿主无关原语)
3
+ *
4
+ * 注意:这不是 OpenCode 依赖。Core 只依赖 Node 内建能力(child_process),
5
+ * 默认实现 NodeCommandRunner 可直接在单测/本地使用;plugin 层如需
6
+ * 经由 OpenCode shell 域执行,可用 setCommandRunner() 注入替代实现。
7
+ *
8
+ * 纪律(来自经验沉淀 opencode-run-hang-watchdog.md):
9
+ * 命令一律带超时,禁止无限等待。默认 120s。
10
+ */
11
+ export interface CommandOptions {
12
+ /** 工作目录 */
13
+ cwd?: string;
14
+ /** 超时毫秒数,默认 120000;超时后进程被终止并返回 timedOut: true */
15
+ timeoutMs?: number;
16
+ /** 附加环境变量(在 process.env 之上合并) */
17
+ env?: Record<string, string>;
18
+ }
19
+ export interface CommandResult {
20
+ command: string;
21
+ /** 退出码;进程被信号杀死或启动失败时为 null */
22
+ code: number | null;
23
+ stdout: string;
24
+ stderr: string;
25
+ timedOut: boolean;
26
+ }
27
+ export interface CommandRunner {
28
+ run(command: string, options?: CommandOptions): Promise<CommandResult>;
29
+ }
30
+ export declare const DEFAULT_COMMAND_TIMEOUT_MS = 120000;
31
+ /** 基于 node:child_process 的默认实现 */
32
+ export declare class NodeCommandRunner implements CommandRunner {
33
+ run(command: string, options?: CommandOptions): Promise<CommandResult>;
34
+ }
35
+ /** 注入自定义 CommandRunner(测试替身 / plugin 层替代实现) */
36
+ export declare function setCommandRunner(value: CommandRunner): void;
37
+ /** 获取当前 CommandRunner */
38
+ export declare function getCommandRunner(): CommandRunner;
@@ -0,0 +1,61 @@
1
+ /**
2
+ * CommandRunner —— 命令执行抽象(Workflow Core 内的宿主无关原语)
3
+ *
4
+ * 注意:这不是 OpenCode 依赖。Core 只依赖 Node 内建能力(child_process),
5
+ * 默认实现 NodeCommandRunner 可直接在单测/本地使用;plugin 层如需
6
+ * 经由 OpenCode shell 域执行,可用 setCommandRunner() 注入替代实现。
7
+ *
8
+ * 纪律(来自经验沉淀 opencode-run-hang-watchdog.md):
9
+ * 命令一律带超时,禁止无限等待。默认 120s。
10
+ */
11
+ import { spawn } from "node:child_process";
12
+ export const DEFAULT_COMMAND_TIMEOUT_MS = 120_000;
13
+ /** 基于 node:child_process 的默认实现 */
14
+ export class NodeCommandRunner {
15
+ async run(command, options) {
16
+ const timeoutMs = options?.timeoutMs ?? DEFAULT_COMMAND_TIMEOUT_MS;
17
+ return new Promise((resolve) => {
18
+ const child = spawn(command, {
19
+ shell: true,
20
+ cwd: options?.cwd,
21
+ env: options?.env ? { ...process.env, ...options.env } : process.env,
22
+ });
23
+ let stdout = "";
24
+ let stderr = "";
25
+ let timedOut = false;
26
+ let settled = false;
27
+ const timer = setTimeout(() => {
28
+ timedOut = true;
29
+ child.kill("SIGKILL");
30
+ }, timeoutMs);
31
+ child.stdout?.on("data", (chunk) => {
32
+ stdout += chunk.toString();
33
+ });
34
+ child.stderr?.on("data", (chunk) => {
35
+ stderr += chunk.toString();
36
+ });
37
+ const finish = (code) => {
38
+ if (settled)
39
+ return;
40
+ settled = true;
41
+ clearTimeout(timer);
42
+ resolve({ command, code, stdout, stderr, timedOut });
43
+ };
44
+ child.on("error", (error) => {
45
+ stderr += String(error.message);
46
+ finish(null);
47
+ });
48
+ child.on("close", (code) => finish(code));
49
+ });
50
+ }
51
+ }
52
+ let runner = new NodeCommandRunner();
53
+ /** 注入自定义 CommandRunner(测试替身 / plugin 层替代实现) */
54
+ export function setCommandRunner(value) {
55
+ runner = value;
56
+ }
57
+ /** 获取当前 CommandRunner */
58
+ export function getCommandRunner() {
59
+ return runner;
60
+ }
61
+ //# sourceMappingURL=command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command.js","sourceRoot":"","sources":["../../src/runtime/command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAwB1C,MAAM,CAAC,MAAM,0BAA0B,GAAG,OAAO,CAAA;AAEjD,kCAAkC;AAClC,MAAM,OAAO,iBAAiB;IAC5B,KAAK,CAAC,GAAG,CAAC,OAAe,EAAE,OAAwB;QACjD,MAAM,SAAS,GAAG,OAAO,EAAE,SAAS,IAAI,0BAA0B,CAAA;QAElE,OAAO,IAAI,OAAO,CAAgB,CAAC,OAAO,EAAE,EAAE;YAC5C,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE;gBAC3B,KAAK,EAAE,IAAI;gBACX,GAAG,EAAE,OAAO,EAAE,GAAG;gBACjB,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG;aACrE,CAAC,CAAA;YAEF,IAAI,MAAM,GAAG,EAAE,CAAA;YACf,IAAI,MAAM,GAAG,EAAE,CAAA;YACf,IAAI,QAAQ,GAAG,KAAK,CAAA;YACpB,IAAI,OAAO,GAAG,KAAK,CAAA;YAEnB,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC5B,QAAQ,GAAG,IAAI,CAAA;gBACf,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;YACvB,CAAC,EAAE,SAAS,CAAC,CAAA;YAEb,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;gBACzC,MAAM,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAA;YAC5B,CAAC,CAAC,CAAA;YACF,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;gBACzC,MAAM,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAA;YAC5B,CAAC,CAAC,CAAA;YAEF,MAAM,MAAM,GAAG,CAAC,IAAmB,EAAE,EAAE;gBACrC,IAAI,OAAO;oBAAE,OAAM;gBACnB,OAAO,GAAG,IAAI,CAAA;gBACd,YAAY,CAAC,KAAK,CAAC,CAAA;gBACnB,OAAO,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAA;YACtD,CAAC,CAAA;YAED,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAY,EAAE,EAAE;gBACjC,MAAM,IAAI,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;gBAC/B,MAAM,CAAC,IAAI,CAAC,CAAA;YACd,CAAC,CAAC,CAAA;YACF,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAA;QAC3C,CAAC,CAAC,CAAA;IACJ,CAAC;CACF;AAED,IAAI,MAAM,GAAkB,IAAI,iBAAiB,EAAE,CAAA;AAEnD,+CAA+C;AAC/C,MAAM,UAAU,gBAAgB,CAAC,KAAoB;IACnD,MAAM,GAAG,KAAK,CAAA;AAChB,CAAC;AAED,yBAAyB;AACzB,MAAM,UAAU,gBAAgB;IAC9B,OAAO,MAAM,CAAA;AACf,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * WorkflowEngine —— 绑定 executor 并执行 workflow 函数
3
+ *
4
+ * P0 语义:
5
+ * engine.run(workflowFn)
6
+ * -> 绑定当前 executor(模块级)
7
+ * -> 执行 workflowFn(内部调用 agent()/parallel()/sequence()/phase())
8
+ * -> 恢复原 executor,返回 workflowFn 的返回值
9
+ *
10
+ * P0 不做:retry / timeout / verify / checkpoint / journal。
11
+ */
12
+ import type { AgentExecutor } from "./executor.js";
13
+ /** 显式设置全局 executor(供 plugin 初始化时注入 OpenCodeV2Executor) */
14
+ export declare function setExecutor(executor: AgentExecutor): void;
15
+ /** 获取当前 executor;未绑定时抛错(workflow 必须在 engine.run 内执行) */
16
+ export declare function requireExecutor(): AgentExecutor;
17
+ export declare function runWorkflow<T>(workflow: () => Promise<T>): Promise<T>;
@@ -0,0 +1,31 @@
1
+ /**
2
+ * WorkflowEngine —— 绑定 executor 并执行 workflow 函数
3
+ *
4
+ * P0 语义:
5
+ * engine.run(workflowFn)
6
+ * -> 绑定当前 executor(模块级)
7
+ * -> 执行 workflowFn(内部调用 agent()/parallel()/sequence()/phase())
8
+ * -> 恢复原 executor,返回 workflowFn 的返回值
9
+ *
10
+ * P0 不做:retry / timeout / verify / checkpoint / journal。
11
+ */
12
+ /** 当前绑定的 executor(模块级;P0 不处理并发嵌套引擎) */
13
+ let currentExecutor;
14
+ /** 显式设置全局 executor(供 plugin 初始化时注入 OpenCodeV2Executor) */
15
+ export function setExecutor(executor) {
16
+ currentExecutor = executor;
17
+ }
18
+ /** 获取当前 executor;未绑定时抛错(workflow 必须在 engine.run 内执行) */
19
+ export function requireExecutor() {
20
+ if (!currentExecutor) {
21
+ throw new Error("[agentic-workflow] no executor bound: run workflows inside engine.run() or call setExecutor() first");
22
+ }
23
+ return currentExecutor;
24
+ }
25
+ export async function runWorkflow(workflow) {
26
+ if (!currentExecutor) {
27
+ throw new Error("[agentic-workflow] engine has no executor: call setExecutor() before runWorkflow()");
28
+ }
29
+ return workflow();
30
+ }
31
+ //# sourceMappingURL=engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/runtime/engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,uCAAuC;AACvC,IAAI,eAA0C,CAAA;AAE9C,0DAA0D;AAC1D,MAAM,UAAU,WAAW,CAAC,QAAuB;IACjD,eAAe,GAAG,QAAQ,CAAA;AAC5B,CAAC;AAED,wDAAwD;AACxD,MAAM,UAAU,eAAe;IAC7B,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CACb,qGAAqG,CACtG,CAAA;IACH,CAAC;IACD,OAAO,eAAe,CAAA;AACxB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAI,QAA0B;IAC7D,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,oFAAoF,CAAC,CAAA;IACvG,CAAC;IACD,OAAO,QAAQ,EAAE,CAAA;AACnB,CAAC"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Workflow 错误分类法(P1.3 失败语义的基础)
3
+ *
4
+ * 统一家族:所有「workflow 层」的失败都继承 WorkflowError,
5
+ * 后续 retry / fallback(P1.4)只捕获该家族,业务异常经 cause 链保留。
6
+ */
7
+ /** workflow 层失败信号的基类 */
8
+ export declare class WorkflowError extends Error {
9
+ constructor(message: string, options?: {
10
+ cause?: unknown;
11
+ });
12
+ }
13
+ /** 单个步骤失败:携带步骤位置与原始异常 */
14
+ export declare class WorkflowStepError extends WorkflowError {
15
+ readonly stepIndex: number;
16
+ readonly stepName?: string;
17
+ constructor(stepIndex: number, cause: unknown, stepName?: string);
18
+ }
19
+ /** sequence 整体失败:fail-fast(1 条)或 continue(累积多条) */
20
+ export declare class WorkflowSequenceError extends WorkflowError {
21
+ /** 按发生顺序排列的步骤失败 */
22
+ readonly errors: WorkflowStepError[];
23
+ /** 最后一次成功步骤的返回值(失败后仍可取已产出结果) */
24
+ readonly lastValue: unknown;
25
+ constructor(errors: WorkflowStepError[], lastValue: unknown);
26
+ }
27
+ /** parallel 任务失败:fail-fast(首个)或 collect(全部) */
28
+ export interface ParallelFailure {
29
+ /** 失败任务的序号(0 起) */
30
+ index: number;
31
+ error: unknown;
32
+ }
33
+ /** parallel 整体失败 */
34
+ export declare class WorkflowParallelError extends WorkflowError {
35
+ readonly failures: ParallelFailure[];
36
+ /** 成功任务的结果(失败槽位为 undefined);fail-fast 下可能不完整 */
37
+ readonly results: ReadonlyArray<unknown>;
38
+ readonly mode: string;
39
+ constructor(failures: ParallelFailure[], results: ReadonlyArray<unknown>, mode: string);
40
+ }
41
+ /** retry 重试耗尽 */
42
+ export declare class WorkflowRetryError extends WorkflowError {
43
+ /** 已尝试次数(含首次) */
44
+ readonly attempts: number;
45
+ /** 最后一次失败的原始异常(通常为 WorkflowError 家族成员) */
46
+ readonly lastError: unknown;
47
+ readonly label: string;
48
+ constructor(attempts: number, lastError: unknown, label: string);
49
+ }
50
+ /** fallback 全部候选失败 */
51
+ export declare class WorkflowFallbackError extends WorkflowError {
52
+ /** 按尝试顺序排列的各候选失败 */
53
+ readonly errors: unknown[];
54
+ readonly label: string;
55
+ constructor(errors: unknown[], label: string);
56
+ }
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Workflow 错误分类法(P1.3 失败语义的基础)
3
+ *
4
+ * 统一家族:所有「workflow 层」的失败都继承 WorkflowError,
5
+ * 后续 retry / fallback(P1.4)只捕获该家族,业务异常经 cause 链保留。
6
+ */
7
+ /** workflow 层失败信号的基类 */
8
+ export class WorkflowError extends Error {
9
+ constructor(message, options) {
10
+ super(message, options);
11
+ this.name = "WorkflowError";
12
+ }
13
+ }
14
+ /** 单个步骤失败:携带步骤位置与原始异常 */
15
+ export class WorkflowStepError extends WorkflowError {
16
+ stepIndex;
17
+ stepName;
18
+ constructor(stepIndex, cause, stepName) {
19
+ const message = cause instanceof Error ? cause.message : String(cause);
20
+ super(`step #${stepIndex}${stepName ? ` (${stepName})` : ""} failed: ${message}`, { cause });
21
+ this.name = "WorkflowStepError";
22
+ this.stepIndex = stepIndex;
23
+ this.stepName = stepName;
24
+ }
25
+ }
26
+ /** sequence 整体失败:fail-fast(1 条)或 continue(累积多条) */
27
+ export class WorkflowSequenceError extends WorkflowError {
28
+ /** 按发生顺序排列的步骤失败 */
29
+ errors;
30
+ /** 最后一次成功步骤的返回值(失败后仍可取已产出结果) */
31
+ lastValue;
32
+ constructor(errors, lastValue) {
33
+ super(`sequence failed (${errors.length} step${errors.length > 1 ? "s" : ""}): ` +
34
+ errors.map((e) => e.message).join("; "));
35
+ this.name = "WorkflowSequenceError";
36
+ this.errors = errors;
37
+ this.lastValue = lastValue;
38
+ }
39
+ }
40
+ /** parallel 整体失败 */
41
+ export class WorkflowParallelError extends WorkflowError {
42
+ failures;
43
+ /** 成功任务的结果(失败槽位为 undefined);fail-fast 下可能不完整 */
44
+ results;
45
+ mode;
46
+ constructor(failures, results, mode) {
47
+ super(`parallel failed (${failures.length} task${failures.length > 1 ? "s" : ""}, mode=${mode}): ` +
48
+ failures
49
+ .map((f) => `#${f.index}: ${f.error instanceof Error ? f.error.message : String(f.error)}`)
50
+ .join("; "));
51
+ this.name = "WorkflowParallelError";
52
+ this.failures = failures;
53
+ this.results = results;
54
+ this.mode = mode;
55
+ }
56
+ }
57
+ /** retry 重试耗尽 */
58
+ export class WorkflowRetryError extends WorkflowError {
59
+ /** 已尝试次数(含首次) */
60
+ attempts;
61
+ /** 最后一次失败的原始异常(通常为 WorkflowError 家族成员) */
62
+ lastError;
63
+ label;
64
+ constructor(attempts, lastError, label) {
65
+ const message = lastError instanceof Error ? lastError.message : String(lastError);
66
+ super(`retry exhausted (${attempts} attempts${label ? `, ${label}` : ""}): ${message}`, {
67
+ cause: lastError,
68
+ });
69
+ this.name = "WorkflowRetryError";
70
+ this.attempts = attempts;
71
+ this.lastError = lastError;
72
+ this.label = label;
73
+ }
74
+ }
75
+ /** fallback 全部候选失败 */
76
+ export class WorkflowFallbackError extends WorkflowError {
77
+ /** 按尝试顺序排列的各候选失败 */
78
+ errors;
79
+ label;
80
+ constructor(errors, label) {
81
+ super(`fallback exhausted (${errors.length} candidate${errors.length > 1 ? "s" : ""}${label ? `, ${label}` : ""}): ` +
82
+ errors.map((e) => (e instanceof Error ? e.message : String(e))).join("; "));
83
+ this.name = "WorkflowFallbackError";
84
+ this.errors = errors;
85
+ this.label = label;
86
+ }
87
+ }
88
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/runtime/errors.ts"],"names":[],"mappings":"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"}