@agentteams/runner 0.0.111 → 0.0.113

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.
@@ -0,0 +1,359 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { createWriteStream } from 'node:fs';
3
+ import { mkdir, rm, writeFile } from 'node:fs/promises';
4
+ import { platform } from 'node:os';
5
+ import { dirname, join } from 'node:path';
6
+ import { describeExecutableResolution, resolveExecutablePathWithPreference } from '../executable.js';
7
+ import { logger } from '../logger.js';
8
+ import { selectRunnerFailureMessage } from './failure-message.js';
9
+ import { setupCloseWatchdog, terminateRunnerChild } from './process-control.js';
10
+ const OUTPUT_PREVIEW_MAX = 400;
11
+ const OUTPUT_CAPTURE_MAX = 200_000;
12
+ // Kiro CLI는 파이프(비-TTY)로 리다이렉트해도 stdout/stderr에 ANSI 이스케이프를 남기고,
13
+ // NO_COLOR=1이나 TERM=dumb으로도 완전히 제거되지 않는다(2026-08-08 실측). 구조화 출력
14
+ // 플래그가 없어 raw 텍스트를 그대로 흘려야 하므로, 최소한의 텍스트 정규화로 ANSI만
15
+ // 제거해 히스토리·실패 메시지에 제어 문자가 노출되지 않게 한다.
16
+ // CSI(`ESC [ … final`), OSC(`ESC ] … BEL|ST`), 그 밖의 2바이트 ESC 시퀀스를 모두 덮는다.
17
+ const ANSI_ESCAPE_PATTERN =
18
+ // eslint-disable-next-line no-control-regex
19
+ /\u001B\[[0-?]*[\u0020-\u002F]*[@-~]|\u001B\][\s\S]*?(?:\u0007|\u001B\\)|\u001B[@-Z\\-_]/gu;
20
+ export const stripAnsiSequences = (value) => value.replace(ANSI_ESCAPE_PATTERN, '');
21
+ /**
22
+ * ANSI 제거를 청크 경계에 걸쳐서도 성립시키는 스트림 정규화기.
23
+ *
24
+ * `stripAnsiSequences`를 data 이벤트마다 개별 적용하면 `ESC[38;5;141m` 한 시퀀스가
25
+ * 두 청크로 쪼개져 도착했을 때 양쪽 어디에도 매치되지 않아 raw 제어 문자가 그대로
26
+ * 히스토리·실패 메시지에 남는다. 마지막 미완결 `ESC` 이후 꼬리를 다음 청크로 넘겨
27
+ * 이어 붙인 뒤 판정한다.
28
+ *
29
+ * `\r`는 스피너 덮어쓰기 용도라 텍스트로는 의미가 없어 함께 제거한다.
30
+ */
31
+ export const createAnsiStripper = () => {
32
+ // 가장 긴 ANSI 시퀀스(OSC)도 이 길이를 넘기 전에 종결자가 오므로, 그보다 길어진
33
+ // 꼬리는 시퀀스가 아니라 그냥 ESC 문자가 섞인 텍스트로 보고 붙잡아 두지 않는다.
34
+ const MAX_PENDING_ESCAPE = 64;
35
+ const ESCAPE = '\u001B';
36
+ let carry = '';
37
+ return {
38
+ push: (chunk) => {
39
+ const stripped = stripAnsiSequences(carry + chunk).replaceAll('\r', '');
40
+ // 완결된 시퀀스는 이미 제거됐으므로, 남은 ESC는 아직 끝나지 않은 것뿐이다.
41
+ const lastEscape = stripped.lastIndexOf(ESCAPE);
42
+ if (lastEscape === -1 || stripped.length - lastEscape > MAX_PENDING_ESCAPE) {
43
+ carry = '';
44
+ return stripped.replaceAll(ESCAPE, '');
45
+ }
46
+ carry = stripped.slice(lastEscape);
47
+ return stripped.slice(0, lastEscape);
48
+ },
49
+ // 미완결 ESC로 끝난 꼬리는 제어 문자라 최종 산출물에 넣지 않는다.
50
+ flush: () => {
51
+ carry = '';
52
+ return '';
53
+ },
54
+ };
55
+ };
56
+ const normalizedModel = (model) => (typeof model === 'string' ? model.trim() : '');
57
+ /**
58
+ * `--model`은 실측으로 확인된 플래그다(`kiro-cli chat --model <MODEL>`, 2026-08-08).
59
+ * 잘못된 값은 exit 1과 함께 사용 가능 목록을 stderr에 출력하므로 조용한 폴백은 없다.
60
+ * `default`는 모델 미지정을 뜻하는 플랫폼 내부 sentinel이라 전달하지 않는다
61
+ * (Kiro 자체의 기본값은 `auto`이며, 그 값은 실제 모델 식별자이므로 그대로 전달한다).
62
+ *
63
+ * 프롬프트는 위치 인자라서 `-`로 시작하면 clap이 플래그로 오인해 usage 출력만 남기고
64
+ * 종료한다(실측). 따라서 항상 `--` 구분자 뒤에 둔다.
65
+ */
66
+ export const buildKiroCliArgs = (prompt, model) => {
67
+ const selectedModel = normalizedModel(model);
68
+ const modelArgs = selectedModel.length > 0 && selectedModel !== 'default' ? ['--model', selectedModel] : [];
69
+ return ['chat', '--no-interactive', '--trust-all-tools', ...modelArgs, '--', prompt];
70
+ };
71
+ export const getKiroExecutablePreference = (isWindows) => isWindows ? ['kiro-cli.exe', 'kiro-cli'] : ['kiro-cli'];
72
+ const toPowerShellLiteral = (value) => `'${value.replaceAll("'", "''")}'`;
73
+ export const toKiroPowerShellEncodedCommand = (resolvedExecutablePath, promptFilePath, model) => {
74
+ const selectedModel = normalizedModel(model);
75
+ const modelSegment = selectedModel.length > 0 && selectedModel !== 'default' ? ` '--model' ${toPowerShellLiteral(selectedModel)}` : '';
76
+ const scriptContent = [
77
+ "$ErrorActionPreference = 'Stop'",
78
+ '$utf8NoBom = [System.Text.UTF8Encoding]::new($false)',
79
+ '[Console]::InputEncoding = $utf8NoBom',
80
+ '[Console]::OutputEncoding = $utf8NoBom',
81
+ '$OutputEncoding = $utf8NoBom',
82
+ 'chcp 65001 > $null',
83
+ `$promptText = [System.IO.File]::ReadAllText(${toPowerShellLiteral(promptFilePath)}, $utf8NoBom)`,
84
+ `& ${toPowerShellLiteral(resolvedExecutablePath)} 'chat' '--no-interactive' '--trust-all-tools'${modelSegment} '--' $promptText`,
85
+ ].join('\r\n');
86
+ return Buffer.from(scriptContent, 'utf16le').toString('base64');
87
+ };
88
+ const toOutputPreview = (text) => {
89
+ const trimmed = text.trim();
90
+ return trimmed.length <= OUTPUT_PREVIEW_MAX ? trimmed : `${trimmed.slice(0, OUTPUT_PREVIEW_MAX)}...`;
91
+ };
92
+ /**
93
+ * Kiro CLI는 정상 실행 중에도 stderr로 신뢰 경고 배너와 종료 시 크레딧 요약
94
+ * (`▸ Credits: N • Time: Ns`)을 보낸다. 그래서 "마지막 stderr 청크"를 그대로 실패
95
+ * 사유로 쓰면 진짜 원인 대신 이런 진행 로그가 실릴 수 있다.
96
+ *
97
+ * 판정은 허용목록이 아니라 **차단목록**이다. 오류 문구를 열거하는 방식은 Kiro의
98
+ * 대표 실패 문구 `Bedrock error message: The model returned the following errors: ...`
99
+ * 처럼 줄 첫머리가 `error`가 아닌 형태를 통째로 놓치고, 그러면 크레딧 요약이 실패
100
+ * 사유로 올라온다. Kiro는 구조화 출력이 없어 오류 형태를 미리 알 수 없으므로,
101
+ * 알려진 진행 로그만 제외하고 나머지 stderr는 전부 오류 후보로 본다.
102
+ */
103
+ const PROGRESS_ONLY_LINE_PATTERNS = [
104
+ // 신뢰 배너: `--trust-all-tools`가 실행마다 출력한다.
105
+ /all tools are now trusted/i,
106
+ // 종료 요약: `▸ Credits: 0.03 • Time: 2s`
107
+ /^[▸>*-]?\s*credits:\s/i,
108
+ /^time:\s/i,
109
+ ];
110
+ const isProgressOnlyOutput = (text) => {
111
+ const lines = text
112
+ .split('\n')
113
+ .map((line) => line.trim())
114
+ .filter((line) => line.length > 0);
115
+ // 제어 문자만 남은 청크(빈 문자열)도 진행 로그로 본다.
116
+ return lines.every((line) => PROGRESS_ONLY_LINE_PATTERNS.some((pattern) => pattern.test(line)));
117
+ };
118
+ const looksLikeErrorOutput = (text) => text.trim().length > 0 && !isProgressOnlyOutput(text);
119
+ const defaultDependencies = {
120
+ platform,
121
+ resolveExecutablePathWithPreference,
122
+ describeExecutableResolution,
123
+ spawn,
124
+ createWriteStream,
125
+ mkdir,
126
+ writeFile,
127
+ rm,
128
+ setupCloseWatchdog,
129
+ terminateRunnerChild,
130
+ };
131
+ export class KiroCliRunner {
132
+ deps;
133
+ constructor(dependencies = {}) {
134
+ this.deps = { ...defaultDependencies, ...dependencies };
135
+ }
136
+ async run(opts) {
137
+ if (!opts.authPath || opts.authPath.trim().length === 0) {
138
+ logger.error('authPath is missing for trigger');
139
+ return { exitCode: 1, errorMessage: 'authPath is missing for trigger' };
140
+ }
141
+ const cwd = opts.authPath;
142
+ const logPath = join(cwd, '.agentteams', 'runner', 'log', `${opts.triggerId}.log`);
143
+ await this.deps.mkdir(dirname(logPath), { recursive: true });
144
+ const isWindows = this.deps.platform() === 'win32';
145
+ const resolvedExecutablePath = this.deps.resolveExecutablePathWithPreference('kiro-cli', getKiroExecutablePreference(isWindows));
146
+ const windowsPromptFilePath = isWindows
147
+ ? join(cwd, '.agentteams', 'runner', 'tmp', `${opts.triggerId}.prompt.txt`)
148
+ : null;
149
+ if (windowsPromptFilePath) {
150
+ await this.deps.mkdir(dirname(windowsPromptFilePath), { recursive: true });
151
+ await this.deps.writeFile(windowsPromptFilePath, opts.prompt, { encoding: 'utf8' });
152
+ }
153
+ const removeWindowsPromptFile = async () => {
154
+ if (!windowsPromptFilePath)
155
+ return;
156
+ try {
157
+ await this.deps.rm(windowsPromptFilePath, { force: true });
158
+ }
159
+ catch (error) {
160
+ logger.warn('Failed to remove Windows prompt temp file', {
161
+ triggerId: opts.triggerId,
162
+ promptFilePath: windowsPromptFilePath,
163
+ error: error instanceof Error ? error.message : String(error),
164
+ });
165
+ }
166
+ };
167
+ const args = buildKiroCliArgs(opts.prompt, opts.model);
168
+ const executableInfo = this.deps.describeExecutableResolution('kiro-cli', {
169
+ platform: () => (isWindows ? 'win32' : this.deps.platform()),
170
+ });
171
+ logger.info('Runner prompt prepared', {
172
+ triggerId: opts.triggerId,
173
+ promptLength: opts.prompt.length,
174
+ requestedCommand: executableInfo.requestedCommand,
175
+ resolvedExecutablePath,
176
+ platform: executableInfo.platform,
177
+ shell: false,
178
+ detached: !isWindows,
179
+ windowsWrapper: isWindows ? 'powershell.exe -EncodedCommand' : null,
180
+ });
181
+ const env = {
182
+ ...process.env,
183
+ AGENTTEAMS_API_KEY: opts.apiKey,
184
+ AGENTTEAMS_API_URL: opts.apiUrl,
185
+ AGENTTEAMS_TEAM_ID: opts.teamId,
186
+ AGENTTEAMS_PROJECT_ID: opts.projectId,
187
+ AGENTTEAMS_AGENT_NAME: opts.agentConfigId,
188
+ };
189
+ let child;
190
+ try {
191
+ child = isWindows
192
+ ? this.deps.spawn('powershell.exe', [
193
+ '-NoLogo',
194
+ '-NonInteractive',
195
+ '-ExecutionPolicy',
196
+ 'Bypass',
197
+ '-EncodedCommand',
198
+ toKiroPowerShellEncodedCommand(resolvedExecutablePath, windowsPromptFilePath ?? '', opts.model),
199
+ ], { cwd, detached: false, shell: false, windowsHide: true, stdio: ['ignore', 'pipe', 'pipe'], env })
200
+ : this.deps.spawn(resolvedExecutablePath, args, {
201
+ cwd,
202
+ detached: true,
203
+ shell: false,
204
+ windowsHide: true,
205
+ stdio: ['ignore', 'pipe', 'pipe'],
206
+ env,
207
+ });
208
+ }
209
+ catch (error) {
210
+ await removeWindowsPromptFile();
211
+ const message = error instanceof Error ? error.message : String(error);
212
+ logger.error('Runner process launch failed', { triggerId: opts.triggerId, error: message });
213
+ return { exitCode: 1, errorMessage: message };
214
+ }
215
+ const logStream = this.deps.createWriteStream(logPath, { flags: 'a' });
216
+ logStream.on('error', (error) => logger.warn('Runner log stream error', { triggerId: opts.triggerId, error: error.message }));
217
+ child.stdout?.pipe(logStream);
218
+ child.stderr?.pipe(logStream);
219
+ let lastOutput = '';
220
+ let lastErrorOutput = '';
221
+ let firstErrorSignal = '';
222
+ let outputText = '';
223
+ const appendOutputText = (chunk) => {
224
+ if (outputText.length < OUTPUT_CAPTURE_MAX) {
225
+ outputText += chunk.slice(0, OUTPUT_CAPTURE_MAX - outputText.length);
226
+ }
227
+ };
228
+ // stdout과 stderr는 서로 다른 스트림이라 ESC 캐리 버퍼도 각각 가져야 한다.
229
+ const stdoutStripper = createAnsiStripper();
230
+ const stderrStripper = createAnsiStripper();
231
+ const idleTimer = { reset: () => { } };
232
+ child.stdout?.on('data', (chunk) => {
233
+ const rawOutput = Buffer.isBuffer(chunk) ? chunk.toString('utf8') : String(chunk);
234
+ // Kiro는 구조화 출력이 없으므로 stdout은 최종 답변 본문 그대로다. ANSI만 벗겨 담는다.
235
+ const text = stdoutStripper.push(rawOutput);
236
+ appendOutputText(text);
237
+ const output = toOutputPreview(text);
238
+ if (output.length > 0) {
239
+ lastOutput = output;
240
+ idleTimer.reset();
241
+ opts.onStdoutChunk?.(output, 'TEXT');
242
+ logger.info('Runner stdout', { triggerId: opts.triggerId, pid: child.pid, output });
243
+ }
244
+ });
245
+ child.stderr?.on('data', (chunk) => {
246
+ const rawOutput = Buffer.isBuffer(chunk) ? chunk.toString('utf8') : String(chunk);
247
+ const output = toOutputPreview(stderrStripper.push(rawOutput));
248
+ if (output.length > 0) {
249
+ lastErrorOutput = output;
250
+ // 첫 오류를 고정한다. 원인 뒤에는 재시도 안내·요약 같은 후속 출력이 붙기 마련이라
251
+ // "마지막 오류 청크"를 쓰면 진짜 원인이 다시 밀려난다.
252
+ if (firstErrorSignal.length === 0 && looksLikeErrorOutput(output)) {
253
+ firstErrorSignal = output;
254
+ }
255
+ idleTimer.reset();
256
+ // Kiro CLI sends the trust banner, cursor control sequences, and the closing
257
+ // `Credits: N • Time: Ns` summary to stderr on successful runs. Keep the raw stream
258
+ // in the runner log, but do not expose it as an error or result.
259
+ logger.info('Kiro CLI progress', { triggerId: opts.triggerId, pid: child.pid, output });
260
+ }
261
+ });
262
+ logger.info('Runner started', { triggerId: opts.triggerId, cwd, logPath, pid: child.pid });
263
+ return await new Promise((resolve) => {
264
+ let finished = false;
265
+ let timedOut = false;
266
+ let idleTimedOut = false;
267
+ let cancelled = false;
268
+ let idleTimeoutId = null;
269
+ const startIdleTimeout = () => {
270
+ if (idleTimeoutId)
271
+ clearTimeout(idleTimeoutId);
272
+ idleTimeoutId = setTimeout(() => {
273
+ idleTimedOut = true;
274
+ timedOut = true;
275
+ logger.warn('Runner idle timeout reached; no output for configured idle period', {
276
+ triggerId: opts.triggerId,
277
+ idleTimeoutMs: opts.idleTimeoutMs,
278
+ });
279
+ this.deps.terminateRunnerChild(child, isWindows, opts.triggerId, 'timeout');
280
+ }, opts.idleTimeoutMs);
281
+ };
282
+ idleTimer.reset = startIdleTimeout;
283
+ startIdleTimeout();
284
+ const handleAbort = () => {
285
+ cancelled = true;
286
+ this.deps.terminateRunnerChild(child, isWindows, opts.triggerId, 'cancel');
287
+ };
288
+ const cleanup = async () => {
289
+ if (finished)
290
+ return;
291
+ finished = true;
292
+ if (idleTimeoutId)
293
+ clearTimeout(idleTimeoutId);
294
+ idleTimer.reset = () => { };
295
+ logStream.end();
296
+ await removeWindowsPromptFile();
297
+ opts.signal?.removeEventListener('abort', handleAbort);
298
+ };
299
+ const timeoutId = setTimeout(() => {
300
+ timedOut = true;
301
+ this.deps.terminateRunnerChild(child, isWindows, opts.triggerId, 'timeout');
302
+ }, opts.timeoutMs);
303
+ if (opts.signal?.aborted)
304
+ handleAbort();
305
+ else
306
+ opts.signal?.addEventListener('abort', handleAbort, { once: true });
307
+ child.on('error', async (error) => {
308
+ clearTimeout(timeoutId);
309
+ await cleanup();
310
+ logger.error('Runner process launch failed', { triggerId: opts.triggerId, error: error.message });
311
+ resolve({ exitCode: 1, lastOutput, outputText: outputText.trim() || undefined, errorMessage: error.message });
312
+ });
313
+ const closeWatchdog = this.deps.setupCloseWatchdog(child, opts.triggerId);
314
+ child.on('close', async (code) => {
315
+ closeWatchdog.cancel();
316
+ clearTimeout(timeoutId);
317
+ await cleanup();
318
+ logger.info('Runner process closed', { triggerId: opts.triggerId, pid: child.pid, exitCode: code, timedOut });
319
+ appendOutputText(stdoutStripper.flush());
320
+ // 마지막 청크가 미완결 ESC로 끝났더라도 최종 산출물에는 제어 문자가 남지 않는다.
321
+ const finalizedOutputText = stripAnsiSequences(outputText).trim() || undefined;
322
+ if (timedOut) {
323
+ resolve({
324
+ exitCode: 1,
325
+ idleTimedOut,
326
+ lastOutput,
327
+ outputText: finalizedOutputText,
328
+ errorMessage: idleTimedOut
329
+ ? `Runner idle timed out after ${Math.round(opts.idleTimeoutMs / 60_000)}m of no output`
330
+ : `Runner fail-safe timed out after ${Math.round(opts.timeoutMs / 3_600_000)}h`,
331
+ });
332
+ return;
333
+ }
334
+ if (cancelled) {
335
+ resolve({
336
+ exitCode: 1,
337
+ cancelled: true,
338
+ lastOutput,
339
+ outputText: finalizedOutputText,
340
+ errorMessage: 'Runner cancelled by user',
341
+ });
342
+ return;
343
+ }
344
+ resolve({
345
+ exitCode: code ?? 1,
346
+ lastOutput,
347
+ outputText: finalizedOutputText,
348
+ errorMessage: selectRunnerFailureMessage({
349
+ exitCode: code,
350
+ // 크레딧 요약 같은 진행 로그가 실패 사유를 덮지 않도록 첫 오류 청크를 우선한다.
351
+ lastErrorOutput: firstErrorSignal || lastErrorOutput,
352
+ lastOutput,
353
+ }),
354
+ });
355
+ });
356
+ });
357
+ }
358
+ }
359
+ //# sourceMappingURL=kiro-cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kiro-cli.js","sourceRoot":"","sources":["../../src/runners/kiro-cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,214 @@
1
+ import { EventEmitter } from 'node:events';
2
+ import { PassThrough } from 'node:stream';
3
+ import assert from 'node:assert/strict';
4
+ import test from 'node:test';
5
+ import { buildKiroCliArgs, createAnsiStripper, getKiroExecutablePreference, KiroCliRunner, stripAnsiSequences, toKiroPowerShellEncodedCommand, } from './kiro-cli.js';
6
+ const ESC = '\u001B';
7
+ test('buildKiroCliArgs uses the headless chat contract with trusted tools', () => {
8
+ assert.deepEqual(buildKiroCliArgs('hello', null), ['chat', '--no-interactive', '--trust-all-tools', '--', 'hello']);
9
+ assert.deepEqual(buildKiroCliArgs('hello', 'default'), [
10
+ 'chat',
11
+ '--no-interactive',
12
+ '--trust-all-tools',
13
+ '--',
14
+ 'hello',
15
+ ]);
16
+ });
17
+ test('buildKiroCliArgs forwards the selected model, including the Kiro default `auto`', () => {
18
+ // `auto`는 Kiro의 실제 모델 식별자(기본값)라서 그대로 전달한다.
19
+ assert.deepEqual(buildKiroCliArgs('hello', 'auto'), [
20
+ 'chat',
21
+ '--no-interactive',
22
+ '--trust-all-tools',
23
+ '--model',
24
+ 'auto',
25
+ '--',
26
+ 'hello',
27
+ ]);
28
+ assert.deepEqual(buildKiroCliArgs('hello', 'claude-haiku-4.5'), [
29
+ 'chat',
30
+ '--no-interactive',
31
+ '--trust-all-tools',
32
+ '--model',
33
+ 'claude-haiku-4.5',
34
+ '--',
35
+ 'hello',
36
+ ]);
37
+ });
38
+ test('buildKiroCliArgs puts the prompt after `--` so a dash-leading prompt is not parsed as a flag', () => {
39
+ // 실측: 구분자 없이 `-`로 시작하는 프롬프트를 주면 clap이 플래그로 오인해
40
+ // usage만 출력하고 모델을 호출하지 않는다.
41
+ const args = buildKiroCliArgs('- 첫 번째 항목', 'auto');
42
+ const separatorIndex = args.indexOf('--');
43
+ assert.notEqual(separatorIndex, -1);
44
+ assert.equal(args[separatorIndex + 1], '- 첫 번째 항목');
45
+ assert.equal(args[args.length - 1], '- 첫 번째 항목');
46
+ });
47
+ test('buildKiroCliArgs omits flags that were not verified against the real CLI', () => {
48
+ const args = buildKiroCliArgs('hello', 'auto');
49
+ // `--effort`는 잘못된 레벨도 조용히 수용되고 low/max가 동일 크레딧을 소모해
50
+ // 효과를 실증하지 못했다. 미확인 플래그는 인자에 넣지 않는다.
51
+ assert.equal(args.includes('--effort'), false);
52
+ assert.equal(args.includes('--agent'), false);
53
+ assert.equal(args.includes('--require-mcp-startup'), false);
54
+ assert.equal(args.includes('--resume'), false);
55
+ });
56
+ test('uses platform-specific Kiro executable preferences', () => {
57
+ assert.deepEqual(getKiroExecutablePreference(false), ['kiro-cli']);
58
+ assert.deepEqual(getKiroExecutablePreference(true), ['kiro-cli.exe', 'kiro-cli']);
59
+ });
60
+ test('stripAnsiSequences removes the escape codes Kiro emits even when piped', () => {
61
+ assert.equal(stripAnsiSequences(`${ESC}[38;5;141m> ${ESC}[0mOK`), '> OK');
62
+ assert.equal(stripAnsiSequences(`${ESC}[32mAll tools are now trusted${ESC}[0m`), 'All tools are now trusted');
63
+ assert.equal(stripAnsiSequences(`${ESC}[?25l${ESC}[1G${ESC}[0m done${ESC}[?25h`), ' done');
64
+ assert.equal(stripAnsiSequences('plain text'), 'plain text');
65
+ });
66
+ test('createAnsiStripper removes an escape sequence split across chunk boundaries', () => {
67
+ const stripper = createAnsiStripper();
68
+ // 한 시퀀스가 두 data 이벤트에 걸쳐 도착하는 경우: 청크 단위 제거로는 어느 쪽도 매치되지 않는다.
69
+ assert.equal(stripper.push(`Kiro ${ESC}[38;5`), 'Kiro ');
70
+ assert.equal(stripper.push(';141mresult'), 'result');
71
+ assert.equal(stripper.flush(), '');
72
+ });
73
+ test('createAnsiStripper drops spinner carriage returns and a dangling escape tail', () => {
74
+ const stripper = createAnsiStripper();
75
+ assert.equal(stripper.push('working\rdone'), 'workingdone');
76
+ assert.equal(stripper.push(`tail${ESC}[`), 'tail');
77
+ assert.equal(stripper.flush(), '');
78
+ });
79
+ test('createAnsiStripper releases a tail that is too long to be an escape sequence', () => {
80
+ const stripper = createAnsiStripper();
81
+ const notASequence = `${ESC}${'x'.repeat(80)}`;
82
+ // 종결자 없이 길어진 꼬리를 계속 붙잡고 있으면 출력이 통째로 사라진다.
83
+ assert.equal(stripper.push(notASequence), 'x'.repeat(80));
84
+ });
85
+ const decodePowerShellCommand = (encoded) => Buffer.from(encoded, 'base64').toString('utf16le');
86
+ test('toKiroPowerShellEncodedCommand reads the prompt from a file and preserves Kiro arguments', () => {
87
+ const script = decodePowerShellCommand(toKiroPowerShellEncodedCommand('C:/kiro-cli.exe', 'C:/repo/.agentteams/runner/tmp/trigger.prompt.txt', 'claude-haiku-4.5'));
88
+ assert.match(script, /\[System\.IO\.File\]::ReadAllText/);
89
+ assert.match(script, /'chat' '--no-interactive' '--trust-all-tools' '--model' 'claude-haiku-4\.5' '--' \$promptText/);
90
+ });
91
+ test('toKiroPowerShellEncodedCommand omits the internal default model sentinel', () => {
92
+ const script = decodePowerShellCommand(toKiroPowerShellEncodedCommand('C:/kiro-cli.exe', 'C:/repo/.agentteams/runner/tmp/trigger.prompt.txt', 'default'));
93
+ assert.match(script, /'chat' '--no-interactive' '--trust-all-tools' '--' \$promptText/);
94
+ assert.doesNotMatch(script, /--model/);
95
+ });
96
+ const createFakeChild = () => {
97
+ const child = new EventEmitter();
98
+ child.pid = 4343;
99
+ child.stdout = new PassThrough();
100
+ child.stderr = new PassThrough();
101
+ return child;
102
+ };
103
+ const createRunner = (emit, spawned) => {
104
+ const child = createFakeChild();
105
+ const runner = new KiroCliRunner({
106
+ platform: () => 'linux',
107
+ resolveExecutablePathWithPreference: (() => '/home/user/.local/bin/kiro-cli'),
108
+ describeExecutableResolution: (() => ({
109
+ requestedCommand: 'kiro-cli',
110
+ resolvedExecutablePath: '/home/user/.local/bin/kiro-cli',
111
+ platform: 'linux',
112
+ shell: false,
113
+ })),
114
+ mkdir: (async () => undefined),
115
+ createWriteStream: (() => new PassThrough()),
116
+ setupCloseWatchdog: (() => ({ cancel: () => { } })),
117
+ spawn: ((command, args, options) => {
118
+ spawned?.push({ command, args, options });
119
+ queueMicrotask(() => emit(child));
120
+ return child;
121
+ }),
122
+ });
123
+ return [runner, child];
124
+ };
125
+ const baseOptions = {
126
+ triggerId: 'trigger-kiro',
127
+ prompt: 'hello',
128
+ authPath: '/repo',
129
+ apiKey: 'key',
130
+ apiUrl: 'https://api.example.com',
131
+ teamId: 'team',
132
+ projectId: 'project',
133
+ timeoutMs: 1_000,
134
+ idleTimeoutMs: 1_000,
135
+ agentConfigId: 'agent',
136
+ };
137
+ test('KiroCliRunner launches headless chat and captures ANSI-stripped text output', async () => {
138
+ const spawned = [];
139
+ const [runner] = createRunner((child) => {
140
+ child.stdout.emit('data', Buffer.from(`${ESC}[38;5;141m> ${ESC}[0mKiro result`));
141
+ // 정상 실행에서도 stderr로 신뢰 배너와 크레딧 요약이 나온다.
142
+ child.stderr.emit('data', Buffer.from(`${ESC}[32mAll tools are now trusted${ESC}[0m`));
143
+ child.stderr.emit('data', Buffer.from(' \u25B8 Credits: 0.03 \u2022 Time: 2s'));
144
+ child.emit('close', 0);
145
+ }, spawned);
146
+ const result = await runner.run({
147
+ ...baseOptions,
148
+ model: 'claude-haiku-4.5',
149
+ onStderrChunk: () => assert.fail('Kiro stderr progress must not be reported as an error chunk'),
150
+ });
151
+ assert.equal(result.exitCode, 0);
152
+ assert.equal(result.outputText, '> Kiro result');
153
+ assert.equal(result.lastOutput, '> Kiro result');
154
+ assert.equal(result.errorMessage, undefined);
155
+ assert.equal(spawned[0]?.command, '/home/user/.local/bin/kiro-cli');
156
+ assert.deepEqual(spawned[0]?.args, [
157
+ 'chat',
158
+ '--no-interactive',
159
+ '--trust-all-tools',
160
+ '--model',
161
+ 'claude-haiku-4.5',
162
+ '--',
163
+ 'hello',
164
+ ]);
165
+ assert.equal(spawned[0]?.options.windowsHide, true);
166
+ });
167
+ test('reports the real stderr cause instead of the trailing progress line on failure', async () => {
168
+ const [runner] = createRunner((child) => {
169
+ child.stderr.emit('data', Buffer.from("error: Model 'bogus-model-xyz' does not exist. Available models: auto, claude-sonnet-4.5"));
170
+ // 오류 이후에도 커서 복원 시퀀스 같은 진행 로그가 뒤따를 수 있다.
171
+ child.stderr.emit('data', Buffer.from(`${ESC}[1G${ESC}[?25h`));
172
+ child.emit('close', 1);
173
+ });
174
+ const result = await runner.run({ ...baseOptions, triggerId: 'trigger-kiro-model-error' });
175
+ assert.equal(result.exitCode, 1);
176
+ assert.match(result.errorMessage ?? '', /Model 'bogus-model-xyz' does not exist/);
177
+ });
178
+ test('surfaces the MCP startup failure cause behind exit code 3', async () => {
179
+ const [runner] = createRunner((child) => {
180
+ child.stderr.emit('data', Buffer.from('Error: One or more MCP servers failed to start'));
181
+ child.emit('close', 3);
182
+ });
183
+ const result = await runner.run({ ...baseOptions, triggerId: 'trigger-kiro-mcp' });
184
+ assert.equal(result.exitCode, 3);
185
+ assert.match(result.errorMessage ?? '', /MCP servers failed to start/);
186
+ });
187
+ test('keeps the Bedrock error as the cause even though it does not start with "error"', async () => {
188
+ const [runner] = createRunner((child) => {
189
+ child.stderr.emit('data', Buffer.from('Bedrock error message: The model returned the following errors: input_schema is invalid'));
190
+ // 실패한 실행도 종료 직전 크레딧 요약을 stderr로 보낸다. 이게 사유를 덮으면 안 된다.
191
+ child.stderr.emit('data', Buffer.from(' ▸ Credits: 0.01 • Time: 1s'));
192
+ child.emit('close', 1);
193
+ });
194
+ const result = await runner.run({ ...baseOptions, triggerId: 'trigger-kiro-bedrock' });
195
+ assert.match(result.errorMessage ?? '', /Bedrock error message/);
196
+ });
197
+ test('keeps the first error chunk when later output also looks like an error', async () => {
198
+ const [runner] = createRunner((child) => {
199
+ child.stderr.emit('data', Buffer.from('Amazon Q is having trouble responding right now'));
200
+ child.stderr.emit('data', Buffer.from('ERROR: retry limit reached'));
201
+ child.emit('close', 1);
202
+ });
203
+ const result = await runner.run({ ...baseOptions, triggerId: 'trigger-kiro-first-error' });
204
+ assert.match(result.errorMessage ?? '', /having trouble responding/);
205
+ });
206
+ test('falls back to a generic failure message when stderr carried only progress output', async () => {
207
+ const [runner] = createRunner((child) => {
208
+ child.stderr.emit('data', Buffer.from(`${ESC}[?25l${ESC}[?25h`));
209
+ child.emit('close', 1);
210
+ });
211
+ const result = await runner.run({ ...baseOptions, triggerId: 'trigger-kiro-opaque' });
212
+ assert.equal(result.errorMessage, 'Runner exited with code 1');
213
+ });
214
+ //# sourceMappingURL=kiro-cli.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kiro-cli.test.js","sourceRoot":"","sources":["../../src/runners/kiro-cli.test.ts"],"names":[],"mappings":"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"}
@@ -8,9 +8,20 @@ type IssueRef = {
8
8
  * 프롬프트에서 이슈 참조를 추출합니다 (문자열 / Tiptap JSON 모두 지원).
9
9
  */
10
10
  export declare function extractIssueRefsFromPrompt(prompt: string | Record<string, unknown>): IssueRef[];
11
+ /**
12
+ * `agentteams plan link-issue` 호출 인자를 만듭니다.
13
+ *
14
+ * CLI는 러너와 별도 패키지로 배포되므로 여기서 쓰는 액션 이름이 CLI 계약과
15
+ * 어긋나면 런타임 경고로만 조용히 실패합니다. 인자 조립을 분리해 테스트로 고정합니다.
16
+ */
17
+ export declare function buildPlanLinkIssueArgs(planId: string, issue: IssueRef): string[];
11
18
  /**
12
19
  * 트리거 완료 후 origin issue 자동 연결 안전장치를 실행합니다.
13
20
  * fire-and-forget: 실패해도 트리거 완료에 영향 없음.
14
21
  */
15
- export declare function runOriginIssueSafeguard(prompt: string | Record<string, unknown>, historyPath: string | null, authPath: string | null): Promise<void>;
22
+ export interface OriginIssueSafeguardDeps {
23
+ /** 테스트에서 CLI 실행을 가로채기 위한 seam. 기본값은 실제 execFile 호출입니다. */
24
+ runCli?: (cwd: string, planId: string, issue: IssueRef) => Promise<void>;
25
+ }
26
+ export declare function runOriginIssueSafeguard(prompt: string | Record<string, unknown>, historyPath: string | null, authPath: string | null, deps?: OriginIssueSafeguardDeps): Promise<void>;
16
27
  export {};