workflow-ai 1.0.14 → 1.0.16

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.
@@ -67,6 +67,12 @@ pipeline:
67
67
  workdir: "."
68
68
  description: "Kilo deepseek"
69
69
 
70
+ kilo-minimax:
71
+ command: "kilo"
72
+ args: ["-m", "kilo/minimax/minimax-m2.5:free", "--agent", "code", "run"]
73
+ workdir: "."
74
+ description: "Kilo minimax"
75
+
70
76
  script-move:
71
77
  command: "node"
72
78
  args: [".workflow/src/scripts/move-ticket.js"]
@@ -270,13 +276,13 @@ pipeline:
270
276
  fallback_agent: kilo-deepseek
271
277
  skill: execute-task
272
278
  counter: task_attempts
273
- # agent_by_type:
274
- # impl: claude-sonnet
275
- # fix: claude-sonnet
276
- # arch: claude-opus
277
- # review: qwen-code
278
- # docs: qwen-code
279
- # plan: claude-opus
279
+ agent_by_type:
280
+ impl: kilo-minimax
281
+ # fix: claude-sonnet
282
+ arch: claude-opus
283
+ # review: qwen-code
284
+ # docs: qwen-code
285
+ admin: kilo-minimax
280
286
  agent_by_attempt:
281
287
  1: qwen-code
282
288
  2: claude-sonnet
@@ -322,7 +328,7 @@ pipeline:
322
328
  review-result:
323
329
  description: "Проверить результат выполнения на соответствие DoD тикета"
324
330
  agent: claude-sonnet
325
- fallback_agent: qwen-code
331
+ fallback_agent: kilo-deepseek
326
332
  skill: review-result
327
333
  counter: task_attempts
328
334
  goto:
@@ -381,7 +387,7 @@ pipeline:
381
387
  create-report:
382
388
  description: "Создать итоговый отчёт по выполненным задачам"
383
389
  agent: claude-sonnet
384
- fallback_agent: qwen-code
390
+ fallback_agent: kilo-deepseek
385
391
  skill: create-report
386
392
  goto:
387
393
  default:
@@ -397,7 +403,7 @@ pipeline:
397
403
  analyze-report:
398
404
  description: "Проанализировать отчёт: план выполнен полностью?"
399
405
  agent: claude-opus
400
- fallback_agent: qwen-code
406
+ fallback_agent: kilo-deepseek
401
407
  skill: analyze-report
402
408
  goto:
403
409
  completed: end
@@ -429,7 +435,7 @@ pipeline:
429
435
  decompose-gaps:
430
436
  description: "Декомпозировать недочёты из отчёта в новые тикеты"
431
437
  agent: claude-sonnet
432
- fallback_agent: qwen-code
438
+ fallback_agent: kilo-deepseek
433
439
  skill: decompose-gaps
434
440
  goto:
435
441
  default: check-conditions
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "workflow-ai",
3
- "version": "1.0.14",
3
+ "version": "1.0.16",
4
4
  "description": "AI Agent Workflow Coordinator — kanban-based pipeline for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {
package/src/lib/utils.mjs CHANGED
@@ -133,17 +133,8 @@ export function getLastReviewStatus(content) {
133
133
  });
134
134
 
135
135
  if (dataRows.length > 0) {
136
- // Ищем строку с самой поздней датой (при равных последняя по позиции)
137
- let latestRow = dataRows[0];
138
- let latestDate = '';
139
- for (const row of dataRows) {
140
- const cells = row.split('|').map(c => c.trim()).filter(c => c);
141
- const dateStr = cells[0] || '';
142
- if (dateStr >= latestDate) {
143
- latestDate = dateStr;
144
- latestRow = row;
145
- }
146
- }
136
+ // Последняя строка таблицы = самое свежее ревью (записи ведутся хронологически сверху вниз)
137
+ const latestRow = dataRows[dataRows.length - 1];
147
138
  const cells = latestRow.split('|').map(c => c.trim()).filter(c => c);
148
139
  const statusRaw = cells[1]?.toLowerCase() || '';
149
140
  if (statusRaw.includes('passed')) return 'passed';
@@ -154,16 +145,8 @@ export function getLastReviewStatus(content) {
154
145
  // Пробуем распарсить текстовый формат (список)
155
146
  const listItems = reviewSection.split('\n').filter(line => line.trim().match(/^[-*]\s/));
156
147
  if (listItems.length > 0) {
157
- // Ищем элемент с самой поздней датой (при равных — последний по позиции)
158
- let latestItem = listItems[0].trim();
159
- let latestDate = '';
160
- for (const item of listItems) {
161
- const dateMatch = item.match(/(\d{4}-\d{2}-\d{2})/);
162
- if (dateMatch && dateMatch[1] >= latestDate) {
163
- latestDate = dateMatch[1];
164
- latestItem = item.trim();
165
- }
166
- }
148
+ // Последний элемент списка = самое свежее ревью (записи ведутся хронологически)
149
+ const latestItem = listItems[listItems.length - 1].trim();
167
150
  const statusMatch = latestItem.match(/:\s*(passed|failed)\b/i);
168
151
  if (statusMatch) return statusMatch[1].toLowerCase();
169
152
  }
@@ -19,11 +19,13 @@ description: Проверить результат выполнения зада
19
19
 
20
20
  ## Шаги проверки
21
21
 
22
- ### 0. Проверить наличие предыдущего успешного ревью
22
+ ### 0. Проверить последний статус ревью
23
23
 
24
24
  **До любых проверок** найди в тикете секцию `## Ревью`.
25
25
 
26
- Если секция существует и содержит запись со статусом `passed` (в виде `✅ passed` или просто `passed`) ревью уже пройдено успешно ранее. Немедленно верни результат без выполнения дальнейших проверок:
26
+ Если секция существует и содержит записипосмотри на **последнюю запись** (последняя строка таблицы или последний элемент списка):
27
+
28
+ - Если последняя запись имеет статус `passed` — ревью уже пройдено. Немедленно верни результат:
27
29
 
28
30
  ```
29
31
  ---RESULT---
@@ -32,9 +34,9 @@ issues: []
32
34
  ---RESULT---
33
35
  ```
34
36
 
35
- > Логика: повторная проверка уже прошедшего ревьюлишняя работа. Если задача была одобрена — она одобрена.
37
+ - Если последняя запись имеет статус `failed`**необходима повторная проверка**. Переходи к шагу 1.
36
38
 
37
- Только если ни одной успешной записи нетпереходи к шагу 1.
39
+ > **ВАЖНО:** Проверяй именно ПОСЛЕДНЮЮ запись, а не любую. Если после `passed` появилась `failed` задача требует повторной проверки. Только если последний статус `passed` — можно пропустить.
38
40
 
39
41
  ### 1. Прочитать тикет
40
42
 
@@ -114,7 +116,8 @@ issues:
114
116
  0. Быстрый выход:
115
117
  - Прочитать тикет
116
118
  - Найти секцию "## Ревью"
117
- - Если есть запись с "passed" → вернуть status: passed, остановиться
119
+ - Если последняя запись "passed" → вернуть status: passed, остановиться
120
+ - Если последняя запись "failed" → перейти к шагу 1 (повторная проверка)
118
121
 
119
122
  1. Парсинг тикета:
120
123
  - Извлечь DoD (список критериев)
@@ -138,7 +141,8 @@ issues:
138
141
  5. Вывод результата в формате ---RESULT---
139
142
 
140
143
  6. Пометка тикета о результате ревью:
141
- - Добавить/обновить секцию `## Ревью` в тикете
144
+ - Добавить секцию `## Ревью` в тикете (если её нет — создать с заголовком таблицы)
145
+ - **ВАЖНО: новую запись добавлять В КОНЕЦ таблицы** (последней строкой). Не вставлять перед существующими записями!
142
146
  - Указать:
143
147
  - Дата ревью
144
148
  - Статус: passed/failed
@@ -233,26 +237,18 @@ issues:
233
237
 
234
238
  ## Формат секции ревью в тикете
235
239
 
236
- После проверки skill добавляет в тикет секцию:
240
+ После проверки skill добавляет в тикет секцию. **Новые записи всегда добавляются В КОНЕЦ таблицы** (хронологический порядок: старые сверху, новые снизу):
237
241
 
238
242
  ```markdown
239
243
  ## Ревью
240
244
 
241
245
  | Дата | Статус | Самари |
242
246
  |------|--------|--------|
243
- | 2026-03-03 14:30 | passed | Все критерии DoD выполнены |
244
- | 2026-03-03 15:45 | failed | Не пройдены тесты, отсутствует файл logger.py |
247
+ | 2026-03-03 14:30 | failed | Не пройдены тесты, отсутствует файл logger.py |
248
+ | 2026-03-03 15:45 | passed | Все критерии DoD выполнены после исправления |
245
249
  ```
246
250
 
247
- Или в текстовом формате:
248
-
249
- ```markdown
250
- ## Ревью
251
-
252
- **Дата:** 2026-03-03 14:30
253
- **Статус:** passed/failed
254
- **Самари:** Краткое описание результата (что не так, если failed)
255
- ```
251
+ > **Порядок записей:** хронологический сверху вниз. Последняя строка = последнее ревью. Код `getLastReviewStatus()` определяет статус по последней строке.
256
252
 
257
253
  ## Интеграция с пайплайном
258
254