workflow-ai 1.0.0 → 1.0.2
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/configs/pipeline.yaml +428 -422
- package/package.json +11 -4
- package/src/scripts/check-conditions.js +211 -0
- package/src/scripts/move-ticket.js +0 -1
- package/src/scripts/move-to-ready.js +0 -1
- package/src/scripts/move-to-review.js +0 -1
- package/src/scripts/pick-next-task.js +7 -10
- package/src/wf-loader.mjs +30 -0
- package/templates/ticket-template.md +0 -1
- package/src/skills/check-conditions/SKILL.md +0 -140
package/configs/pipeline.yaml
CHANGED
|
@@ -1,422 +1,428 @@
|
|
|
1
|
-
# =============================================================================
|
|
2
|
-
# Pipeline Configuration — формат конфигурации пайплайна
|
|
3
|
-
# =============================================================================
|
|
4
|
-
# Описывает цепочку этапов (stages), доступных агентов, goto-логику переходов,
|
|
5
|
-
# retry-стратегии и настройки выполнения.
|
|
6
|
-
#
|
|
7
|
-
# Runner читает этот файл и автономно оркестрирует работу:
|
|
8
|
-
# node .workflow/src/runner.mjs --config .workflow/config/pipeline.yaml
|
|
9
|
-
#
|
|
10
|
-
# Переменные в goto.params:
|
|
11
|
-
# $result.* — поля из результата текущего stage
|
|
12
|
-
# $context.* — переменные из секции context (обновляются через params)
|
|
13
|
-
# $counter.* — значения счётчиков (обновляются стейджами type: update-counter)
|
|
14
|
-
# =============================================================================
|
|
15
|
-
|
|
16
|
-
pipeline:
|
|
17
|
-
name: "default"
|
|
18
|
-
version: "1.0"
|
|
19
|
-
|
|
20
|
-
# ===========================================================================
|
|
21
|
-
# Агенты (agents)
|
|
22
|
-
# ===========================================================================
|
|
23
|
-
# Каждый агент — это CLI-инструмент, который runner вызывает через child_process.
|
|
24
|
-
# Формат:
|
|
25
|
-
# <agent-id>:
|
|
26
|
-
# command: <string> — исполняемый файл (должен быть в PATH)
|
|
27
|
-
# args: <string[]> — аргументы командной строки
|
|
28
|
-
# workdir: <string> — рабочая директория (по умолчанию ".")
|
|
29
|
-
# description: <string> — описание агента (опционально)
|
|
30
|
-
#
|
|
31
|
-
# Runner добавляет промпт последним аргументом автоматически.
|
|
32
|
-
# ===========================================================================
|
|
33
|
-
agents:
|
|
34
|
-
claude-sonnet:
|
|
35
|
-
command: "claude"
|
|
36
|
-
args: ["--model", "claude-sonnet-4-6", "--permission-mode", "acceptEdits", "-p"]
|
|
37
|
-
workdir: "."
|
|
38
|
-
description: "Claude Sonnet — быстрая модель для простых задач"
|
|
39
|
-
|
|
40
|
-
claude-opus:
|
|
41
|
-
command: "claude"
|
|
42
|
-
args: ["--model", "claude-opus-4-6", "--permission-mode", "acceptEdits", "-p"]
|
|
43
|
-
workdir: "."
|
|
44
|
-
description: "Claude Opus — мощная модель для сложных задач"
|
|
45
|
-
|
|
46
|
-
qwen-code:
|
|
47
|
-
command: "qwen"
|
|
48
|
-
args: ["-y", "-
|
|
49
|
-
workdir: "."
|
|
50
|
-
description: "Qwen Code — альтернативный агент для независимой проверки"
|
|
51
|
-
|
|
52
|
-
kilo-code:
|
|
53
|
-
command: "kilo"
|
|
54
|
-
args: ["-m", "kilo/minimax/minimax-m2.5:free", "--agent", "orchestrator", "run"]
|
|
55
|
-
workdir: "."
|
|
56
|
-
description: "Kilo Code — агент с мульти-режимами (architect, code, debug)"
|
|
57
|
-
|
|
58
|
-
kilo-glm:
|
|
59
|
-
command: "kilo"
|
|
60
|
-
args: ["-m", "zai-coding-plan/glm-4.7", "--agent", "orchestrator", "run"]
|
|
61
|
-
workdir: "."
|
|
62
|
-
description: "Kilo GLM"
|
|
63
|
-
|
|
64
|
-
kilo-deepseek:
|
|
65
|
-
command: "kilo"
|
|
66
|
-
args: ["-m", "deepseek/deepseek-reasoner", "--agent", "code", "run"]
|
|
67
|
-
workdir: "."
|
|
68
|
-
description: "Kilo deepseek"
|
|
69
|
-
|
|
70
|
-
script-move:
|
|
71
|
-
command: "node"
|
|
72
|
-
args: [".workflow/src/scripts/move-ticket.js"]
|
|
73
|
-
workdir: "."
|
|
74
|
-
description: "Скрипт для перемещения тикетов между директориями"
|
|
75
|
-
|
|
76
|
-
script-pick:
|
|
77
|
-
command: "node"
|
|
78
|
-
args: [".workflow/src/scripts/pick-next-task.js"]
|
|
79
|
-
workdir: "."
|
|
80
|
-
description: "Скрипт для выбора следующего тикета из ready/"
|
|
81
|
-
|
|
82
|
-
script-move-ready:
|
|
83
|
-
command: "node"
|
|
84
|
-
args: [".workflow/src/scripts/move-to-ready.js"]
|
|
85
|
-
workdir: "."
|
|
86
|
-
description: "Скрипт для перемещения тикетов из backlog/ в ready/"
|
|
87
|
-
|
|
88
|
-
script-
|
|
89
|
-
command: "node"
|
|
90
|
-
args: [".workflow/src/scripts/
|
|
91
|
-
workdir: "."
|
|
92
|
-
description: "Скрипт для
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
#
|
|
101
|
-
#
|
|
102
|
-
#
|
|
103
|
-
#
|
|
104
|
-
#
|
|
105
|
-
#
|
|
106
|
-
#
|
|
107
|
-
#
|
|
108
|
-
#
|
|
109
|
-
#
|
|
110
|
-
#
|
|
111
|
-
#
|
|
112
|
-
#
|
|
113
|
-
#
|
|
114
|
-
#
|
|
115
|
-
#
|
|
116
|
-
#
|
|
117
|
-
#
|
|
118
|
-
#
|
|
119
|
-
#
|
|
120
|
-
#
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
stage: move-to-review
|
|
239
|
-
params:
|
|
240
|
-
ticket_id: "$context.ticket_id"
|
|
241
|
-
attempt: "$counter.task_attempts"
|
|
242
|
-
target: review
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
#
|
|
387
|
-
#
|
|
388
|
-
#
|
|
389
|
-
#
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
#
|
|
393
|
-
#
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
#
|
|
398
|
-
#
|
|
399
|
-
# ===========================================================================
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
# ===========================================================================
|
|
404
|
-
protected_files
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
#
|
|
409
|
-
#
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
#
|
|
415
|
-
#
|
|
416
|
-
#
|
|
417
|
-
#
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# Pipeline Configuration — формат конфигурации пайплайна
|
|
3
|
+
# =============================================================================
|
|
4
|
+
# Описывает цепочку этапов (stages), доступных агентов, goto-логику переходов,
|
|
5
|
+
# retry-стратегии и настройки выполнения.
|
|
6
|
+
#
|
|
7
|
+
# Runner читает этот файл и автономно оркестрирует работу:
|
|
8
|
+
# node .workflow/src/runner.mjs --config .workflow/config/pipeline.yaml
|
|
9
|
+
#
|
|
10
|
+
# Переменные в goto.params:
|
|
11
|
+
# $result.* — поля из результата текущего stage
|
|
12
|
+
# $context.* — переменные из секции context (обновляются через params)
|
|
13
|
+
# $counter.* — значения счётчиков (обновляются стейджами type: update-counter)
|
|
14
|
+
# =============================================================================
|
|
15
|
+
|
|
16
|
+
pipeline:
|
|
17
|
+
name: "default"
|
|
18
|
+
version: "1.0"
|
|
19
|
+
|
|
20
|
+
# ===========================================================================
|
|
21
|
+
# Агенты (agents)
|
|
22
|
+
# ===========================================================================
|
|
23
|
+
# Каждый агент — это CLI-инструмент, который runner вызывает через child_process.
|
|
24
|
+
# Формат:
|
|
25
|
+
# <agent-id>:
|
|
26
|
+
# command: <string> — исполняемый файл (должен быть в PATH)
|
|
27
|
+
# args: <string[]> — аргументы командной строки
|
|
28
|
+
# workdir: <string> — рабочая директория (по умолчанию ".")
|
|
29
|
+
# description: <string> — описание агента (опционально)
|
|
30
|
+
#
|
|
31
|
+
# Runner добавляет промпт последним аргументом автоматически.
|
|
32
|
+
# ===========================================================================
|
|
33
|
+
agents:
|
|
34
|
+
claude-sonnet:
|
|
35
|
+
command: "claude"
|
|
36
|
+
args: ["--model", "claude-sonnet-4-6", "--permission-mode", "acceptEdits", "-p"]
|
|
37
|
+
workdir: "."
|
|
38
|
+
description: "Claude Sonnet — быстрая модель для простых задач"
|
|
39
|
+
|
|
40
|
+
claude-opus:
|
|
41
|
+
command: "claude"
|
|
42
|
+
args: ["--model", "claude-opus-4-6", "--permission-mode", "acceptEdits", "-p"]
|
|
43
|
+
workdir: "."
|
|
44
|
+
description: "Claude Opus — мощная модель для сложных задач"
|
|
45
|
+
|
|
46
|
+
qwen-code:
|
|
47
|
+
command: "qwen"
|
|
48
|
+
args: ["-y", "-p"]
|
|
49
|
+
workdir: "."
|
|
50
|
+
description: "Qwen Code — альтернативный агент для независимой проверки"
|
|
51
|
+
|
|
52
|
+
kilo-code:
|
|
53
|
+
command: "kilo"
|
|
54
|
+
args: ["-m", "kilo/minimax/minimax-m2.5:free", "--agent", "orchestrator", "run"]
|
|
55
|
+
workdir: "."
|
|
56
|
+
description: "Kilo Code — агент с мульти-режимами (architect, code, debug)"
|
|
57
|
+
|
|
58
|
+
kilo-glm:
|
|
59
|
+
command: "kilo"
|
|
60
|
+
args: ["-m", "zai-coding-plan/glm-4.7", "--agent", "orchestrator", "run"]
|
|
61
|
+
workdir: "."
|
|
62
|
+
description: "Kilo GLM"
|
|
63
|
+
|
|
64
|
+
kilo-deepseek:
|
|
65
|
+
command: "kilo"
|
|
66
|
+
args: ["-m", "deepseek/deepseek-reasoner", "--agent", "code", "run"]
|
|
67
|
+
workdir: "."
|
|
68
|
+
description: "Kilo deepseek"
|
|
69
|
+
|
|
70
|
+
script-move:
|
|
71
|
+
command: "node"
|
|
72
|
+
args: [".workflow/src/scripts/move-ticket.js"]
|
|
73
|
+
workdir: "."
|
|
74
|
+
description: "Скрипт для перемещения тикетов между директориями"
|
|
75
|
+
|
|
76
|
+
script-pick:
|
|
77
|
+
command: "node"
|
|
78
|
+
args: [".workflow/src/scripts/pick-next-task.js"]
|
|
79
|
+
workdir: "."
|
|
80
|
+
description: "Скрипт для выбора следующего тикета из ready/"
|
|
81
|
+
|
|
82
|
+
script-move-ready:
|
|
83
|
+
command: "node"
|
|
84
|
+
args: [".workflow/src/scripts/move-to-ready.js"]
|
|
85
|
+
workdir: "."
|
|
86
|
+
description: "Скрипт для перемещения тикетов из backlog/ в ready/"
|
|
87
|
+
|
|
88
|
+
script-check-conditions:
|
|
89
|
+
command: "node"
|
|
90
|
+
args: [".workflow/src/scripts/check-conditions.js"]
|
|
91
|
+
workdir: "."
|
|
92
|
+
description: "Скрипт для проверки условий тикетов в backlog/"
|
|
93
|
+
|
|
94
|
+
script-move-to-review:
|
|
95
|
+
command: "node"
|
|
96
|
+
args: [".workflow/src/scripts/move-to-review.js"]
|
|
97
|
+
workdir: "."
|
|
98
|
+
description: "Скрипт для перемещения завершённых тикетов из in-progress/ в review/"
|
|
99
|
+
|
|
100
|
+
# ===========================================================================
|
|
101
|
+
# Этапы (stages)
|
|
102
|
+
# ===========================================================================
|
|
103
|
+
# Каждый stage описывает один шаг пайплайна.
|
|
104
|
+
# Формат:
|
|
105
|
+
# <stage-id>:
|
|
106
|
+
# description: <string> — что делает этот этап
|
|
107
|
+
# agent: <agent-id> — какой агент выполняет (ссылка на agents.*)
|
|
108
|
+
# skill: <skill-id> — какой skill использовать (файл .workflow/src/skills/<skill>/SKILL.md)
|
|
109
|
+
# goto: — логика переходов по результату
|
|
110
|
+
# <status>: — ключ = статус результата агента
|
|
111
|
+
# stage: <stage-id> — следующий stage
|
|
112
|
+
# params: <map> — параметры, передаваемые в context следующего stage
|
|
113
|
+
# default: — fallback если статус не совпал ни с одним ключом
|
|
114
|
+
#
|
|
115
|
+
# Специальные значения stage:
|
|
116
|
+
# "end" — завершение пайплайна
|
|
117
|
+
#
|
|
118
|
+
# Встроенный тип стейджа (type: update-counter):
|
|
119
|
+
# Инкрементирует счётчик без вызова агента.
|
|
120
|
+
# type: update-counter — встроенный обработчик runner'а
|
|
121
|
+
# counter: <string> — имя счётчика
|
|
122
|
+
# max: <int> — при достижении max возвращает статус "max_reached"
|
|
123
|
+
# goto:
|
|
124
|
+
# default: <stage> — следующий стейдж (счётчик < max)
|
|
125
|
+
# max_reached: <stage> — стейдж при достижении max
|
|
126
|
+
# ===========================================================================
|
|
127
|
+
stages:
|
|
128
|
+
|
|
129
|
+
# -------------------------------------------------------------------------
|
|
130
|
+
# 0. pick-first-task
|
|
131
|
+
# Выбирает следующую задачу из ready/ по приоритету и зависимостям
|
|
132
|
+
# Если ready/ пуст — проверяет review/
|
|
133
|
+
# -------------------------------------------------------------------------
|
|
134
|
+
pick-first-task:
|
|
135
|
+
description: "Выбрать задачу задачу из ready по приоритету"
|
|
136
|
+
agent: script-pick
|
|
137
|
+
goto:
|
|
138
|
+
found:
|
|
139
|
+
stage: move-to-in-progress
|
|
140
|
+
params:
|
|
141
|
+
ticket_id: "$result.ticket_id"
|
|
142
|
+
target: in-progress
|
|
143
|
+
in_review:
|
|
144
|
+
stage: review-result
|
|
145
|
+
params:
|
|
146
|
+
ticket_id: "$result.ticket_id"
|
|
147
|
+
attempt: "1"
|
|
148
|
+
completed_in_progress:
|
|
149
|
+
stage: move-to-review
|
|
150
|
+
params:
|
|
151
|
+
ticket_id: "$result.ticket_id"
|
|
152
|
+
empty: check-conditions
|
|
153
|
+
error: create-report
|
|
154
|
+
|
|
155
|
+
# -------------------------------------------------------------------------
|
|
156
|
+
# 1. check-conditions
|
|
157
|
+
# Проверяет условия тикетов в backlog/, выводит список готовых
|
|
158
|
+
# -------------------------------------------------------------------------
|
|
159
|
+
check-conditions:
|
|
160
|
+
description: "Проверить условия тикетов в backlog, вывести готовые"
|
|
161
|
+
agent: script-check-conditions
|
|
162
|
+
goto:
|
|
163
|
+
has_ready:
|
|
164
|
+
stage: move-to-ready
|
|
165
|
+
params:
|
|
166
|
+
ready_tickets: "$result.ready_tickets"
|
|
167
|
+
default: pick-next-task
|
|
168
|
+
empty: create-report
|
|
169
|
+
error: create-report
|
|
170
|
+
|
|
171
|
+
# -------------------------------------------------------------------------
|
|
172
|
+
# 1b. move-to-ready
|
|
173
|
+
# Перемещает тикеты из backlog/ в ready/ (по списку из check-conditions)
|
|
174
|
+
# -------------------------------------------------------------------------
|
|
175
|
+
move-to-ready:
|
|
176
|
+
description: "Переместить готовые тикеты из backlog в ready"
|
|
177
|
+
agent: script-move-ready
|
|
178
|
+
timeout: 120
|
|
179
|
+
goto:
|
|
180
|
+
default: pick-next-task
|
|
181
|
+
|
|
182
|
+
# -------------------------------------------------------------------------
|
|
183
|
+
# 2. pick-next-task
|
|
184
|
+
# Выбирает следующую задачу из ready/ по приоритету и зависимостям
|
|
185
|
+
# Если ready/ пуст — проверяет review/
|
|
186
|
+
# -------------------------------------------------------------------------
|
|
187
|
+
pick-next-task:
|
|
188
|
+
description: "Выбрать следующую задачу из ready по приоритету"
|
|
189
|
+
agent: script-pick
|
|
190
|
+
goto:
|
|
191
|
+
found:
|
|
192
|
+
stage: move-to-in-progress
|
|
193
|
+
params:
|
|
194
|
+
ticket_id: "$result.ticket_id"
|
|
195
|
+
target: in-progress
|
|
196
|
+
in_review:
|
|
197
|
+
stage: review-result
|
|
198
|
+
params:
|
|
199
|
+
ticket_id: "$result.ticket_id"
|
|
200
|
+
attempt: "1"
|
|
201
|
+
completed_in_progress:
|
|
202
|
+
stage: move-to-review
|
|
203
|
+
params:
|
|
204
|
+
ticket_id: "$result.ticket_id"
|
|
205
|
+
empty: check-conditions
|
|
206
|
+
error: create-report
|
|
207
|
+
|
|
208
|
+
# -------------------------------------------------------------------------
|
|
209
|
+
# 2b. move-to-in-progress
|
|
210
|
+
# Перемещает тикет из ready/ в in-progress/ перед выполнением
|
|
211
|
+
# -------------------------------------------------------------------------
|
|
212
|
+
move-to-in-progress:
|
|
213
|
+
description: "Переместить тикет из ready в in-progress"
|
|
214
|
+
agent: script-move
|
|
215
|
+
timeout: 120
|
|
216
|
+
goto:
|
|
217
|
+
default:
|
|
218
|
+
stage: execute-task
|
|
219
|
+
params:
|
|
220
|
+
ticket_id: "$context.ticket_id"
|
|
221
|
+
error:
|
|
222
|
+
stage: execute-task
|
|
223
|
+
params:
|
|
224
|
+
ticket_id: "$context.ticket_id"
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
# -------------------------------------------------------------------------
|
|
228
|
+
# 3. execute-task
|
|
229
|
+
# Выполняет выбранную задачу (код, документация, план и т.д.)
|
|
230
|
+
# -------------------------------------------------------------------------
|
|
231
|
+
execute-task:
|
|
232
|
+
description: "Выполнить выбранную задачу"
|
|
233
|
+
agent: qwen-code
|
|
234
|
+
fallback_agent: kilo-deepseek
|
|
235
|
+
skill: execute-task
|
|
236
|
+
goto:
|
|
237
|
+
default:
|
|
238
|
+
stage: move-to-review
|
|
239
|
+
params:
|
|
240
|
+
ticket_id: "$context.ticket_id"
|
|
241
|
+
attempt: "$counter.task_attempts"
|
|
242
|
+
target: review
|
|
243
|
+
error:
|
|
244
|
+
stage: move-to-review
|
|
245
|
+
params:
|
|
246
|
+
ticket_id: "$context.ticket_id"
|
|
247
|
+
attempt: "$counter.task_attempts"
|
|
248
|
+
target: review
|
|
249
|
+
|
|
250
|
+
# -------------------------------------------------------------------------
|
|
251
|
+
# 3b. move-to-review
|
|
252
|
+
# Перемещает тикет в review/ после выполнения задачи
|
|
253
|
+
# -------------------------------------------------------------------------
|
|
254
|
+
move-to-review:
|
|
255
|
+
description: "Переместить тикет в review после выполнения"
|
|
256
|
+
agent: script-move-to-review
|
|
257
|
+
timeout: 120
|
|
258
|
+
goto:
|
|
259
|
+
default:
|
|
260
|
+
stage: review-result
|
|
261
|
+
params:
|
|
262
|
+
ticket_id: "$context.ticket_id"
|
|
263
|
+
attempt: "$counter.task_attempts"
|
|
264
|
+
|
|
265
|
+
# -------------------------------------------------------------------------
|
|
266
|
+
# 4. review-result
|
|
267
|
+
# Проверяет результат выполнения на соответствие DoD тикета.
|
|
268
|
+
# Использует независимый агент (qwen-code) для объективной оценки.
|
|
269
|
+
# При failed — переходит на increment-task-attempts для учёта попытки.
|
|
270
|
+
# -------------------------------------------------------------------------
|
|
271
|
+
review-result:
|
|
272
|
+
description: "Проверить результат выполнения на соответствие DoD тикета"
|
|
273
|
+
agent: claude-sonnet
|
|
274
|
+
fallback_agent: qwen-code
|
|
275
|
+
skill: review-result
|
|
276
|
+
goto:
|
|
277
|
+
passed:
|
|
278
|
+
stage: move-ticket
|
|
279
|
+
params:
|
|
280
|
+
ticket_id: "$context.ticket_id"
|
|
281
|
+
target: done
|
|
282
|
+
failed:
|
|
283
|
+
stage: increment-task-attempts
|
|
284
|
+
params:
|
|
285
|
+
ticket_id: "$context.ticket_id"
|
|
286
|
+
default:
|
|
287
|
+
stage: move-ticket
|
|
288
|
+
params:
|
|
289
|
+
ticket_id: "$context.ticket_id"
|
|
290
|
+
target: blocked
|
|
291
|
+
|
|
292
|
+
# -------------------------------------------------------------------------
|
|
293
|
+
# 4b. increment-task-attempts
|
|
294
|
+
# Отдельный стейдж обновления счётчика попыток выполнения тикета.
|
|
295
|
+
# При достижении max — блокирует тикет. Иначе — возвращает в очередь.
|
|
296
|
+
# -------------------------------------------------------------------------
|
|
297
|
+
increment-task-attempts:
|
|
298
|
+
description: "Обновить счётчик попыток выполнения тикета"
|
|
299
|
+
type: update-counter
|
|
300
|
+
counter: task_attempts
|
|
301
|
+
max: 3
|
|
302
|
+
goto:
|
|
303
|
+
default:
|
|
304
|
+
stage: move-ticket
|
|
305
|
+
params:
|
|
306
|
+
ticket_id: "$context.ticket_id"
|
|
307
|
+
target: ready
|
|
308
|
+
max_reached:
|
|
309
|
+
stage: move-ticket
|
|
310
|
+
params:
|
|
311
|
+
ticket_id: "$context.ticket_id"
|
|
312
|
+
target: blocked
|
|
313
|
+
|
|
314
|
+
# -------------------------------------------------------------------------
|
|
315
|
+
# 5. move-ticket
|
|
316
|
+
# Перемещает тикет в целевую директорию (done/ или blocked/)
|
|
317
|
+
# -------------------------------------------------------------------------
|
|
318
|
+
move-ticket:
|
|
319
|
+
description: "Переместить тикет (done / blocked)"
|
|
320
|
+
agent: script-move
|
|
321
|
+
timeout: 120
|
|
322
|
+
goto:
|
|
323
|
+
default: pick-next-task
|
|
324
|
+
|
|
325
|
+
# -------------------------------------------------------------------------
|
|
326
|
+
# 6. create-report
|
|
327
|
+
# Создаёт итоговый отчёт по выполненным задачам текущего цикла
|
|
328
|
+
# -------------------------------------------------------------------------
|
|
329
|
+
create-report:
|
|
330
|
+
description: "Создать итоговый отчёт по выполненным задачам"
|
|
331
|
+
agent: claude-sonnet
|
|
332
|
+
fallback_agent: qwen-code
|
|
333
|
+
skill: create-report
|
|
334
|
+
goto:
|
|
335
|
+
default:
|
|
336
|
+
stage: analyze-report
|
|
337
|
+
params:
|
|
338
|
+
report_id: "$result.report_id"
|
|
339
|
+
|
|
340
|
+
# -------------------------------------------------------------------------
|
|
341
|
+
# 7. analyze-report
|
|
342
|
+
# Анализирует отчёт: план выполнен полностью или есть пробелы?
|
|
343
|
+
# При has_gaps — переходит на increment-plan-iterations для учёта итерации.
|
|
344
|
+
# -------------------------------------------------------------------------
|
|
345
|
+
analyze-report:
|
|
346
|
+
description: "Проанализировать отчёт: план выполнен полностью?"
|
|
347
|
+
agent: claude-opus
|
|
348
|
+
fallback_agent: qwen-code
|
|
349
|
+
skill: analyze-report
|
|
350
|
+
goto:
|
|
351
|
+
completed: end
|
|
352
|
+
has_gaps:
|
|
353
|
+
stage: increment-plan-iterations
|
|
354
|
+
params:
|
|
355
|
+
gaps: "$result.gaps"
|
|
356
|
+
report_id: "$context.report_id"
|
|
357
|
+
|
|
358
|
+
# -------------------------------------------------------------------------
|
|
359
|
+
# 7b. increment-plan-iterations
|
|
360
|
+
# Отдельный стейдж обновления счётчика итераций анализа плана.
|
|
361
|
+
# При достижении max — завершает пайплайн. Иначе — декомпозирует пробелы.
|
|
362
|
+
# -------------------------------------------------------------------------
|
|
363
|
+
increment-plan-iterations:
|
|
364
|
+
description: "Обновить счётчик итераций анализа плана"
|
|
365
|
+
type: update-counter
|
|
366
|
+
counter: plan_iterations
|
|
367
|
+
max: 3
|
|
368
|
+
goto:
|
|
369
|
+
default:
|
|
370
|
+
stage: decompose-gaps
|
|
371
|
+
max_reached: end
|
|
372
|
+
|
|
373
|
+
# -------------------------------------------------------------------------
|
|
374
|
+
# 8. decompose-gaps
|
|
375
|
+
# Декомпозирует недочёты из анализа отчёта в новые тикеты (backlog/)
|
|
376
|
+
# -------------------------------------------------------------------------
|
|
377
|
+
decompose-gaps:
|
|
378
|
+
description: "Декомпозировать недочёты из отчёта в новые тикеты"
|
|
379
|
+
agent: claude-sonnet
|
|
380
|
+
fallback_agent: qwen-code
|
|
381
|
+
skill: decompose-gaps
|
|
382
|
+
goto:
|
|
383
|
+
default: check-conditions
|
|
384
|
+
|
|
385
|
+
# ===========================================================================
|
|
386
|
+
# Точка входа (entry)
|
|
387
|
+
# ===========================================================================
|
|
388
|
+
# Stage, с которого начинается выполнение пайплайна.
|
|
389
|
+
# ===========================================================================
|
|
390
|
+
entry: pick-first-task
|
|
391
|
+
|
|
392
|
+
# ===========================================================================
|
|
393
|
+
# Контекст (context)
|
|
394
|
+
# ===========================================================================
|
|
395
|
+
# Переменные, доступные всем stages через $context.*.
|
|
396
|
+
# Runner автоматически обновляет context через params в goto-переходах.
|
|
397
|
+
# Начальные значения задаются здесь или через CLI:
|
|
398
|
+
# node runner.mjs --plan PLAN-003
|
|
399
|
+
# ===========================================================================
|
|
400
|
+
context:
|
|
401
|
+
plan_id: "" # ID плана (задаётся при запуске)
|
|
402
|
+
|
|
403
|
+
# ===========================================================================
|
|
404
|
+
# Защита файлов (protected_files)
|
|
405
|
+
# ===========================================================================
|
|
406
|
+
# Glob-паттерны файлов, в которые агентам запрещена запись.
|
|
407
|
+
# Runner проверяет эти паттерны и блокирует изменения.
|
|
408
|
+
# Пути указываются относительно корня проекта (без префикса .workflow/)
|
|
409
|
+
# ===========================================================================
|
|
410
|
+
protected_files:
|
|
411
|
+
- ".workflow/plans/**" # Планы — только для чтения
|
|
412
|
+
- ".workflow/config/**" # Конфигурация
|
|
413
|
+
|
|
414
|
+
# ===========================================================================
|
|
415
|
+
# Настройки выполнения (execution)
|
|
416
|
+
# ===========================================================================
|
|
417
|
+
# Параметры, управляющие поведением runner'а.
|
|
418
|
+
#
|
|
419
|
+
# max_steps: — абсолютный лимит шагов за один запуск (защита от зацикливания)
|
|
420
|
+
# delay_between_stages: — пауза между этапами в секундах
|
|
421
|
+
# timeout_per_stage: — таймаут на один этап в секундах (по истечении — ошибка)
|
|
422
|
+
# log_file: — путь к файлу логов (относительно корня проекта)
|
|
423
|
+
# ===========================================================================
|
|
424
|
+
execution:
|
|
425
|
+
max_steps: 100
|
|
426
|
+
delay_between_stages: 5
|
|
427
|
+
timeout_per_stage: 1800
|
|
428
|
+
log_file: ".workflow/logs/pipeline.log"
|