@osolmaz/pi-workflows 0.10.0 → 0.11.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 +23 -12
- package/dist/builtins/autodoc.workflow.d.ts +58 -0
- package/dist/builtins/autodoc.workflow.js +266 -0
- package/dist/builtins/autodoc.workflow.js.map +1 -0
- package/dist/builtins/autoimplement.workflow.d.ts +210 -11
- package/dist/builtins/autoimplement.workflow.js +245 -13
- package/dist/builtins/autoimplement.workflow.js.map +1 -1
- package/dist/builtins/{autodevise.workflow.d.ts → autoplan.workflow.d.ts} +9 -9
- package/dist/builtins/{autodevise.workflow.js → autoplan.workflow.js} +20 -20
- package/dist/builtins/autoplan.workflow.js.map +1 -0
- package/dist/builtins/catalog.js +8 -4
- package/dist/builtins/catalog.js.map +1 -1
- package/dist/builtins/index.d.ts +6 -3
- package/dist/builtins/index.js +5 -2
- package/dist/builtins/index.js.map +1 -1
- package/dist/builtins/monitor.workflow.d.ts +4 -0
- package/dist/builtins/monitor.workflow.js +134 -9
- package/dist/builtins/monitor.workflow.js.map +1 -1
- package/dist/builtins/plan-approval.workflow.d.ts +83 -0
- package/dist/builtins/plan-approval.workflow.js +148 -0
- package/dist/builtins/plan-approval.workflow.js.map +1 -0
- package/dist/builtins/plan-presentation.d.ts +7 -0
- package/dist/builtins/plan-presentation.js +44 -0
- package/dist/builtins/plan-presentation.js.map +1 -0
- package/dist/extension/decision-channels.d.ts +132 -0
- package/dist/extension/decision-channels.js +1082 -0
- package/dist/extension/decision-channels.js.map +1 -0
- package/dist/extension/index.d.ts +1 -0
- package/dist/extension/index.js +426 -11
- package/dist/extension/index.js.map +1 -1
- package/dist/extension/widget.js +26 -2
- package/dist/extension/widget.js.map +1 -1
- package/dist/extension/workflow-tool.d.ts +1 -37
- package/dist/extension/workflow-tool.js +1 -42
- package/dist/extension/workflow-tool.js.map +1 -1
- package/dist/host/rpc-bridge.js +4 -21
- package/dist/host/rpc-bridge.js.map +1 -1
- package/dist/render/graph-render.js +33 -8
- package/dist/render/graph-render.js.map +1 -1
- package/dist/viewer/render.js +36 -2
- package/dist/viewer/render.js.map +1 -1
- package/dist/workflows/composition.js +15 -1
- package/dist/workflows/composition.js.map +1 -1
- package/dist/workflows/decision-presentation.d.ts +18 -0
- package/dist/workflows/decision-presentation.js +417 -0
- package/dist/workflows/decision-presentation.js.map +1 -0
- package/dist/workflows/engine.d.ts +2 -1
- package/dist/workflows/engine.js +86 -4
- package/dist/workflows/engine.js.map +1 -1
- package/dist/workflows/human-decision.d.ts +87 -0
- package/dist/workflows/human-decision.js +583 -0
- package/dist/workflows/human-decision.js.map +1 -0
- package/dist/workflows/index.d.ts +3 -1
- package/dist/workflows/index.js +2 -0
- package/dist/workflows/index.js.map +1 -1
- package/dist/workflows/schema.js +15 -0
- package/dist/workflows/schema.js.map +1 -1
- package/dist/workflows/store.js +7 -0
- package/dist/workflows/store.js.map +1 -1
- package/dist/workflows/tool-input.d.ts +72 -0
- package/dist/workflows/tool-input.js +141 -0
- package/dist/workflows/tool-input.js.map +1 -0
- package/dist/workflows/types.d.ts +223 -0
- package/docs/HUMAN_DECISIONS.md +371 -0
- package/docs/HUMAN_DECISION_PRESENTATIONS.md +323 -0
- package/docs/MONITOR.md +17 -6
- package/docs/WORKFLOW_COMPOSITION.md +13 -6
- package/docs/plans/2026-08-19-human-decision-gates-plan.md +296 -0
- package/docs/plans/2026-08-19-human-decision-presentations-plan.md +172 -0
- package/docs/plans/2026-08-19-provider-compatible-workflow-tool-schema-plan.md +45 -0
- package/docs/plans/2026-08-19-workflow-composition-plan.md +25 -17
- package/docs/run-bundles.md +23 -2
- package/docs/workflows.md +43 -5
- package/examples/workflows/approved-plan.workflow.ts +58 -0
- package/examples/workflows/autoplan.workflow.ts +1 -0
- package/examples/workflows/human-decision.workflow.ts +62 -0
- package/herdr-plugin.toml +1 -1
- package/package.json +2 -1
- package/schemas/decision-presentation-v1.schema.json +83 -0
- package/schemas/human-decision-accepted-v1.schema.json +44 -0
- package/schemas/human-decision-accepted-v2.schema.json +50 -0
- package/schemas/human-decision-answer-attempt-v1.schema.json +37 -0
- package/schemas/human-decision-cancellation-v1.schema.json +15 -0
- package/schemas/human-decision-continuation-v1.schema.json +16 -0
- package/schemas/human-decision-delivery-v1.schema.json +28 -0
- package/schemas/human-decision-delivery-v2.schema.json +36 -0
- package/schemas/human-decision-receipt-v1.schema.json +33 -0
- package/schemas/human-decision-receipt-v2.schema.json +39 -0
- package/schemas/human-decision-request-v1.schema.json +59 -0
- package/schemas/human-decision-request-v2.schema.json +69 -0
- package/schemas/human-decision-resolution-v1.schema.json +27 -0
- package/schemas/human-decision-resolution-v2.schema.json +27 -0
- package/schemas/human-decision-settlement-v1.schema.json +28 -0
- package/skills/autodoc/SKILL.md +43 -0
- package/skills/autoimplement/SKILL.md +58 -0
- package/skills/autoimplement/agents/openai.yaml +4 -0
- package/skills/autoplan/SKILL.md +25 -0
- package/skills/monitor/SKILL.md +3 -1
- package/skills/pi-workflows/SKILL.md +3 -3
- package/src/builtins/autodoc.workflow.ts +325 -0
- package/src/builtins/autoimplement.workflow.ts +281 -14
- package/src/builtins/{autodevise.workflow.ts → autoplan.workflow.ts} +32 -32
- package/src/builtins/catalog.ts +8 -4
- package/src/builtins/index.ts +25 -6
- package/src/builtins/monitor.workflow.ts +162 -8
- package/src/builtins/plan-approval.workflow.ts +190 -0
- package/src/builtins/plan-presentation.ts +57 -0
- package/src/extension/decision-channels.ts +1533 -0
- package/src/extension/index.ts +499 -9
- package/src/extension/widget.ts +39 -2
- package/src/extension/workflow-tool.ts +5 -81
- package/src/host/rpc-bridge.ts +7 -30
- package/src/render/graph-render.ts +40 -3
- package/src/viewer/render.ts +56 -3
- package/src/workflows/composition.ts +16 -1
- package/src/workflows/decision-presentation.ts +501 -0
- package/src/workflows/engine.ts +108 -4
- package/src/workflows/human-decision.ts +819 -0
- package/src/workflows/index.ts +69 -0
- package/src/workflows/schema.ts +17 -0
- package/src/workflows/store.ts +8 -0
- package/src/workflows/tool-input.ts +202 -0
- package/src/workflows/types.ts +265 -0
- package/dist/builtins/autodevise.workflow.js.map +0 -1
- package/examples/workflows/autodevise.workflow.ts +0 -1
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
import { agent, compute, defineWorkflow } from "../workflows/definition.js";
|
|
2
|
+
import { digest } from "../workflows/human-decision.js";
|
|
3
|
+
import type { WorkflowNodeContext } from "../workflows/types.js";
|
|
4
|
+
|
|
5
|
+
export type AutodocInput = {
|
|
6
|
+
task: string;
|
|
7
|
+
plan?: unknown;
|
|
8
|
+
repository?: string;
|
|
9
|
+
documents?: string[];
|
|
10
|
+
evidence?: unknown;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export type DocumentedPlan = {
|
|
14
|
+
status: "ready";
|
|
15
|
+
task: string;
|
|
16
|
+
plan: unknown;
|
|
17
|
+
planDigest: string;
|
|
18
|
+
documentation: {
|
|
19
|
+
state: "current" | "updated";
|
|
20
|
+
files: string[];
|
|
21
|
+
digests: Record<string, string>;
|
|
22
|
+
evidence: unknown;
|
|
23
|
+
};
|
|
24
|
+
verification: unknown;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export type AutodocBlocked = {
|
|
28
|
+
status: "blocked";
|
|
29
|
+
task: string;
|
|
30
|
+
reason: string;
|
|
31
|
+
evidence: unknown;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
type LocatedPlan = {
|
|
35
|
+
route: "found" | "blocked";
|
|
36
|
+
plan?: unknown;
|
|
37
|
+
sources?: string[];
|
|
38
|
+
reason: string;
|
|
39
|
+
evidence: unknown;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
type DocumentationAssessment = {
|
|
43
|
+
route: "current" | "update" | "blocked";
|
|
44
|
+
files: string[];
|
|
45
|
+
digests: Record<string, string>;
|
|
46
|
+
reason: string;
|
|
47
|
+
evidence: unknown;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
function requireRecord(value: unknown, label: string): Record<string, unknown> {
|
|
51
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
52
|
+
throw new Error(`${label} must be an object`);
|
|
53
|
+
}
|
|
54
|
+
return value as Record<string, unknown>;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function requireString(value: unknown, label: string): string {
|
|
58
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
59
|
+
throw new Error(`${label} must be a non-empty string`);
|
|
60
|
+
}
|
|
61
|
+
return value.trim();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function stringArray(value: unknown, label: string): string[] {
|
|
65
|
+
if (!Array.isArray(value) || value.some((item) => typeof item !== "string")) {
|
|
66
|
+
throw new Error(`${label} must be an array of strings`);
|
|
67
|
+
}
|
|
68
|
+
return [...value] as string[];
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function stringRecord(value: unknown, label: string): Record<string, string> {
|
|
72
|
+
if (value === undefined) return {};
|
|
73
|
+
const record = requireRecord(value, label);
|
|
74
|
+
if (Object.values(record).some((item) => typeof item !== "string")) {
|
|
75
|
+
throw new Error(`${label} values must be strings`);
|
|
76
|
+
}
|
|
77
|
+
return record as Record<string, string>;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function parseInput(value: unknown): AutodocInput {
|
|
81
|
+
const input = requireRecord(value, "autodoc input");
|
|
82
|
+
const documents = input.documents;
|
|
83
|
+
return {
|
|
84
|
+
task: requireString(input.task, "autodoc task"),
|
|
85
|
+
...(input.plan !== undefined ? { plan: input.plan } : {}),
|
|
86
|
+
...(input.repository !== undefined
|
|
87
|
+
? { repository: requireString(input.repository, "autodoc repository") }
|
|
88
|
+
: {}),
|
|
89
|
+
...(documents !== undefined ? { documents: stringArray(documents, "autodoc documents") } : {}),
|
|
90
|
+
...(input.evidence !== undefined ? { evidence: input.evidence } : {}),
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function parseLocatedPlan(value: unknown): LocatedPlan {
|
|
95
|
+
const result = requireRecord(value, "located plan");
|
|
96
|
+
if (result.route !== "found" && result.route !== "blocked") {
|
|
97
|
+
throw new Error("located plan route must be found or blocked");
|
|
98
|
+
}
|
|
99
|
+
if (result.route === "found" && result.plan === undefined) {
|
|
100
|
+
throw new Error("located plan must include the selected plan");
|
|
101
|
+
}
|
|
102
|
+
return {
|
|
103
|
+
route: result.route,
|
|
104
|
+
...(result.plan !== undefined ? { plan: result.plan } : {}),
|
|
105
|
+
...(result.sources !== undefined
|
|
106
|
+
? { sources: stringArray(result.sources, "located plan sources") }
|
|
107
|
+
: {}),
|
|
108
|
+
reason: requireString(result.reason, "located plan reason"),
|
|
109
|
+
evidence: result.evidence ?? null,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function parseDocumentationAssessment(value: unknown): DocumentationAssessment {
|
|
114
|
+
const result = requireRecord(value, "documentation assessment");
|
|
115
|
+
if (result.route !== "current" && result.route !== "update" && result.route !== "blocked") {
|
|
116
|
+
throw new Error("documentation assessment route must be current, update, or blocked");
|
|
117
|
+
}
|
|
118
|
+
return {
|
|
119
|
+
route: result.route,
|
|
120
|
+
files: stringArray(result.files, "documentation files"),
|
|
121
|
+
digests: stringRecord(result.digests, "documentation digests"),
|
|
122
|
+
reason: requireString(result.reason, "documentation reason"),
|
|
123
|
+
evidence: result.evidence ?? null,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function currentPlan(context: WorkflowNodeContext): unknown {
|
|
128
|
+
const explicit = (context.input as AutodocInput).plan;
|
|
129
|
+
if (explicit !== undefined) return explicit;
|
|
130
|
+
const located = context.outputs.locatePlan as LocatedPlan | undefined;
|
|
131
|
+
if (located?.route === "found" && located.plan !== undefined) return located.plan;
|
|
132
|
+
throw new Error("autodoc does not have a selected plan");
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function blockedReason(context: WorkflowNodeContext): AutodocBlocked {
|
|
136
|
+
const request = context.input as AutodocInput;
|
|
137
|
+
const assessment = context.outputs.inspectDocumentation as DocumentationAssessment | undefined;
|
|
138
|
+
const located = context.outputs.locatePlan as LocatedPlan | undefined;
|
|
139
|
+
return {
|
|
140
|
+
status: "blocked",
|
|
141
|
+
task: request.task,
|
|
142
|
+
reason:
|
|
143
|
+
assessment?.route === "blocked"
|
|
144
|
+
? assessment.reason
|
|
145
|
+
: located?.route === "blocked"
|
|
146
|
+
? located.reason
|
|
147
|
+
: "Autodoc could not identify a clear selected plan or canonical document target.",
|
|
148
|
+
evidence: assessment?.evidence ?? located?.evidence ?? null,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export const autodocWorkflow = defineWorkflow({
|
|
153
|
+
source: import.meta.url,
|
|
154
|
+
contractId: "pi-workflows.autodoc.v1",
|
|
155
|
+
name: "autodoc",
|
|
156
|
+
input: parseInput,
|
|
157
|
+
title: ({ input }) => `autodoc: ${input.task.slice(0, 60)}`,
|
|
158
|
+
startAt: "prepare",
|
|
159
|
+
maxSteps: 24,
|
|
160
|
+
exits: {
|
|
161
|
+
ready: {
|
|
162
|
+
from: "finalize",
|
|
163
|
+
validate: (value: unknown): DocumentedPlan => value as DocumentedPlan,
|
|
164
|
+
},
|
|
165
|
+
blocked: {
|
|
166
|
+
from: "blocked",
|
|
167
|
+
validate: (value: unknown): AutodocBlocked => value as AutodocBlocked,
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
nodes: {
|
|
171
|
+
prepare: compute({
|
|
172
|
+
run: ({ input }) => ({
|
|
173
|
+
route: (input as AutodocInput).plan === undefined ? "locate" : "inspect",
|
|
174
|
+
}),
|
|
175
|
+
}),
|
|
176
|
+
locatePlan: agent({
|
|
177
|
+
statusDetail: "locating selected plan",
|
|
178
|
+
prompt: ({ input }) => {
|
|
179
|
+
const request = input as AutodocInput;
|
|
180
|
+
return [
|
|
181
|
+
"Find the clear plan that has already been selected for this task.",
|
|
182
|
+
"Look in the current conversation context and in the referenced canonical documents.",
|
|
183
|
+
"Do not devise, improve, replace, or implement the plan.",
|
|
184
|
+
"Return blocked when no single clear selected plan exists.",
|
|
185
|
+
`Task: ${request.task}`,
|
|
186
|
+
`Repository: ${request.repository ?? "current repository"}`,
|
|
187
|
+
`Referenced documents: ${JSON.stringify(request.documents ?? [])}`,
|
|
188
|
+
`Evidence: ${JSON.stringify(request.evidence ?? null)}`,
|
|
189
|
+
].join("\n");
|
|
190
|
+
},
|
|
191
|
+
expectedOutput:
|
|
192
|
+
'{ "route": "found" | "blocked", "plan": {} (required when found), "sources": ["source"], "reason": "reason", "evidence": "evidence" }',
|
|
193
|
+
validate: parseLocatedPlan,
|
|
194
|
+
}),
|
|
195
|
+
inspectDocumentation: agent({
|
|
196
|
+
statusDetail: "checking canonical documentation",
|
|
197
|
+
prompt: (context) => {
|
|
198
|
+
const request = context.input as AutodocInput;
|
|
199
|
+
return [
|
|
200
|
+
"Check whether the selected plan is already recorded completely and accurately in the canonical specification and implementation plan.",
|
|
201
|
+
"Use repository guidance to choose canonical files. Do not redesign or implement anything.",
|
|
202
|
+
"Choose current only when the documents already preserve the whole selected plan and its boundaries.",
|
|
203
|
+
"Choose update when documents are missing or stale and can be corrected in scope.",
|
|
204
|
+
"Choose blocked only when no safe canonical target exists or repository rules prohibit the documentation change.",
|
|
205
|
+
`Task: ${request.task}`,
|
|
206
|
+
`Selected plan: ${JSON.stringify(currentPlan(context))}`,
|
|
207
|
+
`Preferred documents: ${JSON.stringify(request.documents ?? [])}`,
|
|
208
|
+
].join("\n");
|
|
209
|
+
},
|
|
210
|
+
expectedOutput:
|
|
211
|
+
'{ "route": "current" | "update" | "blocked", "files": ["canonical file"], "digests": { "file": "sha256:digest" }, "reason": "reason", "evidence": "evidence" }',
|
|
212
|
+
validate: parseDocumentationAssessment,
|
|
213
|
+
}),
|
|
214
|
+
updateDocumentation: agent({
|
|
215
|
+
timeoutMs: 30 * 60_000,
|
|
216
|
+
statusDetail: "updating canonical documentation",
|
|
217
|
+
prompt: (context) => {
|
|
218
|
+
const request = context.input as AutodocInput;
|
|
219
|
+
const assessment = context.outputs.inspectDocumentation as DocumentationAssessment;
|
|
220
|
+
return [
|
|
221
|
+
"Update the canonical specification and implementation plan to preserve the selected plan exactly.",
|
|
222
|
+
"Use the repository documentation rules and keep the text plain and complete.",
|
|
223
|
+
"Do not redesign the solution and do not implement code.",
|
|
224
|
+
`Task: ${request.task}`,
|
|
225
|
+
`Selected plan: ${JSON.stringify(currentPlan(context))}`,
|
|
226
|
+
`Canonical files: ${JSON.stringify(assessment.files)}`,
|
|
227
|
+
`Assessment: ${JSON.stringify(assessment)}`,
|
|
228
|
+
].join("\n");
|
|
229
|
+
},
|
|
230
|
+
expectedOutput:
|
|
231
|
+
'{ "updated": true, "files": ["changed file"], "digests": { "file": "sha256:digest" }, "summary": "what was recorded" }',
|
|
232
|
+
validate: (value) => {
|
|
233
|
+
const result = requireRecord(value, "documentation update");
|
|
234
|
+
if (result.updated !== true)
|
|
235
|
+
throw new Error("documentation update must report updated: true");
|
|
236
|
+
stringArray(result.files, "updated documentation files");
|
|
237
|
+
stringRecord(result.digests, "updated documentation digests");
|
|
238
|
+
requireString(result.summary, "documentation update summary");
|
|
239
|
+
return result;
|
|
240
|
+
},
|
|
241
|
+
}),
|
|
242
|
+
verifyDocumentation: agent({
|
|
243
|
+
timeoutMs: 20 * 60_000,
|
|
244
|
+
statusDetail: "verifying documentation",
|
|
245
|
+
prompt: ({ outputs }) =>
|
|
246
|
+
[
|
|
247
|
+
"Verify the changed canonical documentation.",
|
|
248
|
+
"Run the repository documentation, formatting, link, and privacy checks that apply.",
|
|
249
|
+
"Do not implement code.",
|
|
250
|
+
`Documentation update: ${JSON.stringify(outputs.updateDocumentation)}`,
|
|
251
|
+
].join("\n"),
|
|
252
|
+
expectedOutput:
|
|
253
|
+
'{ "passed": true | false, "commands": [{ "command": "exact command", "outcome": "result" }], "failures": ["failure"] }',
|
|
254
|
+
validate: (value) => {
|
|
255
|
+
const result = requireRecord(value, "documentation verification");
|
|
256
|
+
if (typeof result.passed !== "boolean") {
|
|
257
|
+
throw new Error("documentation verification passed must be boolean");
|
|
258
|
+
}
|
|
259
|
+
return result;
|
|
260
|
+
},
|
|
261
|
+
}),
|
|
262
|
+
finalize: compute({
|
|
263
|
+
run: (context) => {
|
|
264
|
+
const request = context.input as AutodocInput;
|
|
265
|
+
const assessment = context.outputs.inspectDocumentation as DocumentationAssessment;
|
|
266
|
+
const plan = currentPlan(context);
|
|
267
|
+
const updated = context.outputs.updateDocumentation;
|
|
268
|
+
if (updated === undefined) {
|
|
269
|
+
return {
|
|
270
|
+
status: "ready",
|
|
271
|
+
task: request.task,
|
|
272
|
+
plan,
|
|
273
|
+
planDigest: digest(plan),
|
|
274
|
+
documentation: {
|
|
275
|
+
state: "current",
|
|
276
|
+
files: assessment.files,
|
|
277
|
+
digests: assessment.digests,
|
|
278
|
+
evidence: assessment.evidence,
|
|
279
|
+
},
|
|
280
|
+
verification: { passed: true, reason: "Canonical documentation was already current." },
|
|
281
|
+
} satisfies DocumentedPlan;
|
|
282
|
+
}
|
|
283
|
+
const updateRecord = requireRecord(updated, "documentation update");
|
|
284
|
+
return {
|
|
285
|
+
status: "ready",
|
|
286
|
+
task: request.task,
|
|
287
|
+
plan,
|
|
288
|
+
planDigest: digest(plan),
|
|
289
|
+
documentation: {
|
|
290
|
+
state: "updated",
|
|
291
|
+
files: stringArray(updateRecord.files, "updated documentation files"),
|
|
292
|
+
digests: stringRecord(updateRecord.digests, "updated documentation digests"),
|
|
293
|
+
evidence: context.outputs.verifyDocumentation,
|
|
294
|
+
},
|
|
295
|
+
verification: context.outputs.verifyDocumentation,
|
|
296
|
+
} satisfies DocumentedPlan;
|
|
297
|
+
},
|
|
298
|
+
}),
|
|
299
|
+
blocked: compute({ run: blockedReason }),
|
|
300
|
+
},
|
|
301
|
+
edges: [
|
|
302
|
+
{
|
|
303
|
+
from: "prepare",
|
|
304
|
+
switch: { on: "$.route", cases: { locate: "locatePlan", inspect: "inspectDocumentation" } },
|
|
305
|
+
},
|
|
306
|
+
{
|
|
307
|
+
from: "locatePlan",
|
|
308
|
+
switch: { on: "$.route", cases: { found: "inspectDocumentation", blocked: "blocked" } },
|
|
309
|
+
},
|
|
310
|
+
{
|
|
311
|
+
from: "inspectDocumentation",
|
|
312
|
+
switch: {
|
|
313
|
+
on: "$.route",
|
|
314
|
+
cases: { current: "finalize", update: "updateDocumentation", blocked: "blocked" },
|
|
315
|
+
},
|
|
316
|
+
},
|
|
317
|
+
{ from: "updateDocumentation", to: "verifyDocumentation" },
|
|
318
|
+
{
|
|
319
|
+
from: "verifyDocumentation",
|
|
320
|
+
switch: { on: "$.passed", cases: { true: "finalize", false: "blocked" } },
|
|
321
|
+
},
|
|
322
|
+
],
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
export default autodocWorkflow;
|