workflow-ai 1.0.5 → 1.0.7

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 (2) hide show
  1. package/package.json +1 -1
  2. package/src/runner.mjs +44 -4
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "workflow-ai",
3
- "version": "1.0.5",
3
+ "version": "1.0.7",
4
4
  "description": "AI Agent Workflow Coordinator — kanban-based pipeline for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {
package/src/runner.mjs CHANGED
@@ -771,9 +771,36 @@ class StageExecutor {
771
771
  reject(new Error(`Stage "${stageId}" timed out after ${timeout}s`));
772
772
  }, timeout * 1000);
773
773
 
774
+ let stdoutBuffer = '';
774
775
  child.stdout.on('data', (data) => {
775
- stdout += data.toString();
776
- process.stdout.write(data);
776
+ const chunk = data.toString();
777
+ stdout += chunk;
778
+ // Парсим stream-json и выводим только текст дельт
779
+ stdoutBuffer += chunk;
780
+ const lines = stdoutBuffer.split('\n');
781
+ stdoutBuffer = lines.pop(); // незавершённая строка остаётся в буфере
782
+ for (const line of lines) {
783
+ if (!line.trim()) continue;
784
+ try {
785
+ const obj = JSON.parse(line);
786
+ // Claude: content_block_delta с delta.text
787
+ if (obj.type === 'content_block_delta' && obj.delta?.text) {
788
+ process.stdout.write(obj.delta.text);
789
+ }
790
+ // Qwen/Claude: assistant message с content text
791
+ else if (obj.type === 'assistant' && obj.message?.content) {
792
+ for (const block of obj.message.content) {
793
+ if (block.type === 'text' && block.text) {
794
+ process.stdout.write(block.text);
795
+ }
796
+ }
797
+ }
798
+ // result содержит финальный текст (дублирует assistant) — пропускаем
799
+ } catch {
800
+ // не JSON — выводим как есть
801
+ process.stdout.write(line + '\n');
802
+ }
803
+ }
777
804
  });
778
805
 
779
806
  child.stderr.on('data', (data) => {
@@ -783,6 +810,18 @@ class StageExecutor {
783
810
 
784
811
  child.on('close', (code) => {
785
812
  clearTimeout(timeoutId);
813
+ // Обрабатываем остаток буфера стриминга
814
+ if (stdoutBuffer.trim()) {
815
+ try {
816
+ const obj = JSON.parse(stdoutBuffer);
817
+ if (obj.type === 'content_block_delta' && obj.delta?.text) {
818
+ process.stdout.write(obj.delta.text);
819
+ }
820
+ } catch {
821
+ process.stdout.write(stdoutBuffer + '\n');
822
+ }
823
+ }
824
+ process.stdout.write('\n');
786
825
 
787
826
  if (timedOut) return;
788
827
 
@@ -1084,7 +1123,8 @@ class PipelineRunner {
1084
1123
  return {
1085
1124
  steps: this.stepCount,
1086
1125
  tasksExecuted: this.tasksExecuted,
1087
- context: this.context
1126
+ context: this.context,
1127
+ failed: !this.running && this.stepCount < maxSteps
1088
1128
  };
1089
1129
  }
1090
1130
 
@@ -1420,7 +1460,7 @@ async function runPipeline(argv = process.argv.slice(2)) {
1420
1460
  console.log(`Steps executed: ${result.steps}`);
1421
1461
  console.log(`Tasks completed: ${result.tasksExecuted}`);
1422
1462
 
1423
- return { exitCode: 0, result };
1463
+ return { exitCode: result.failed ? 1 : 0, result };
1424
1464
 
1425
1465
  } catch (err) {
1426
1466
  console.error(`\nError: ${err.message}`);