sentix 2.0.21 → 2.0.22
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/package.json +1 -1
- package/src/lib/pipeline.js +41 -7
package/package.json
CHANGED
package/src/lib/pipeline.js
CHANGED
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
import { spawnSync } from 'node:child_process';
|
|
17
|
+
import { existsSync } from 'node:fs';
|
|
18
|
+
import { join } from 'node:path';
|
|
17
19
|
import { runGates } from './verify-gates.js';
|
|
18
20
|
|
|
19
21
|
/**
|
|
@@ -191,27 +193,59 @@ export async function runChainedPipeline(request, cycleId, state, ctx, options =
|
|
|
191
193
|
};
|
|
192
194
|
}
|
|
193
195
|
|
|
196
|
+
// ── 에이전트 이름 → phase 이름 매핑 ────────────────────
|
|
197
|
+
|
|
198
|
+
const AGENT_MAP = {
|
|
199
|
+
plan: 'planner',
|
|
200
|
+
dev: 'dev',
|
|
201
|
+
review: 'pr-review',
|
|
202
|
+
finalize: null, // finalize는 전용 에이전트 없음
|
|
203
|
+
};
|
|
204
|
+
|
|
194
205
|
// ── Phase 실행 ────────────────────────────────────────
|
|
195
206
|
|
|
196
207
|
function runPhase(name, prompt, ctx) {
|
|
197
|
-
const
|
|
208
|
+
const args = ['-p', prompt, '--output-format', 'json'];
|
|
209
|
+
|
|
210
|
+
// .claude/agents/ 에 에이전트가 있으면 --agent 플래그 추가
|
|
211
|
+
const agentName = AGENT_MAP[name];
|
|
212
|
+
if (agentName && existsSync(join(ctx.cwd, '.claude', 'agents', `${agentName}.md`))) {
|
|
213
|
+
args.push('--agent', agentName);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const result = spawnSync('claude', args, {
|
|
198
217
|
cwd: ctx.cwd,
|
|
199
|
-
|
|
200
|
-
|
|
218
|
+
encoding: 'utf-8',
|
|
219
|
+
stdio: 'pipe',
|
|
220
|
+
timeout: 300_000, // 5분 per phase
|
|
201
221
|
});
|
|
202
222
|
|
|
203
223
|
if (result.error) {
|
|
204
224
|
ctx.error(`Phase ${name} failed: ${result.error.message}`);
|
|
205
|
-
return { success: false, error: result.error.message, exit_code: null };
|
|
225
|
+
return { success: false, error: result.error.message, exit_code: null, output: null };
|
|
206
226
|
}
|
|
207
227
|
|
|
208
228
|
if (result.status !== 0) {
|
|
209
229
|
ctx.error(`Phase ${name} exited with code ${result.status}`);
|
|
210
|
-
|
|
230
|
+
// stderr가 있으면 출력
|
|
231
|
+
if (result.stderr?.trim()) {
|
|
232
|
+
ctx.log(result.stderr.slice(-500));
|
|
233
|
+
}
|
|
234
|
+
return { success: false, error: `exit code ${result.status}`, exit_code: result.status, output: null };
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// JSON 출력 파싱
|
|
238
|
+
let output = null;
|
|
239
|
+
try {
|
|
240
|
+
output = JSON.parse(result.stdout);
|
|
241
|
+
ctx.success(`Phase ${name} completed (${output.usage?.output_tokens || '?'} tokens)`);
|
|
242
|
+
} catch {
|
|
243
|
+
// JSON 파싱 실패 — 텍스트 그대로 사용
|
|
244
|
+
output = { content: result.stdout };
|
|
245
|
+
ctx.success(`Phase ${name} completed`);
|
|
211
246
|
}
|
|
212
247
|
|
|
213
|
-
|
|
214
|
-
return { success: true, error: null, exit_code: 0 };
|
|
248
|
+
return { success: true, error: null, exit_code: 0, output };
|
|
215
249
|
}
|
|
216
250
|
|
|
217
251
|
// ── 최근 티켓 내용 가져오기 ───────────────────────────
|