@agentteams/runner 0.0.113 → 0.0.115

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 (113) hide show
  1. package/dist/api-client.d.ts +7 -0
  2. package/dist/api-client.js +39 -0
  3. package/dist/api-client.js.map +1 -1
  4. package/dist/api-client.test.js +23 -0
  5. package/dist/api-client.test.js.map +1 -1
  6. package/dist/commands/update.js +1 -7
  7. package/dist/commands/update.js.map +1 -1
  8. package/dist/executable.d.ts +19 -2
  9. package/dist/executable.js +144 -7
  10. package/dist/executable.js.map +1 -1
  11. package/dist/executable.test.js +70 -1
  12. package/dist/executable.test.js.map +1 -1
  13. package/dist/handlers/trigger-handler.js +3 -0
  14. package/dist/handlers/trigger-handler.js.map +1 -1
  15. package/dist/poller.d.ts +5 -1
  16. package/dist/poller.js +92 -1
  17. package/dist/poller.js.map +1 -1
  18. package/dist/poller.test.js +187 -0
  19. package/dist/poller.test.js.map +1 -1
  20. package/dist/runners/amp.js +3 -16
  21. package/dist/runners/amp.js.map +1 -1
  22. package/dist/runners/antigravity.js +3 -16
  23. package/dist/runners/antigravity.js.map +1 -1
  24. package/dist/runners/capabilities.d.ts +7 -1
  25. package/dist/runners/capabilities.js +21 -9
  26. package/dist/runners/capabilities.js.map +1 -1
  27. package/dist/runners/capabilities.test.js +12 -0
  28. package/dist/runners/capabilities.test.js.map +1 -1
  29. package/dist/runners/claude-code.js +3 -8
  30. package/dist/runners/claude-code.js.map +1 -1
  31. package/dist/runners/claude-code.test.js +10 -0
  32. package/dist/runners/claude-code.test.js.map +1 -1
  33. package/dist/runners/codex.js +3 -16
  34. package/dist/runners/codex.js.map +1 -1
  35. package/dist/runners/copilot-cli.js +2 -8
  36. package/dist/runners/copilot-cli.js.map +1 -1
  37. package/dist/runners/cursor-cli.js +2 -8
  38. package/dist/runners/cursor-cli.js.map +1 -1
  39. package/dist/runners/cursor-cli.test.js +14 -0
  40. package/dist/runners/cursor-cli.test.js.map +1 -1
  41. package/dist/runners/engine-commands.d.ts +11 -0
  42. package/dist/runners/engine-commands.js +27 -0
  43. package/dist/runners/engine-commands.js.map +1 -0
  44. package/dist/runners/grok-build-identity.d.ts +8 -0
  45. package/dist/runners/grok-build-identity.js +17 -0
  46. package/dist/runners/grok-build-identity.js.map +1 -0
  47. package/dist/runners/grok-build.d.ts +60 -0
  48. package/dist/runners/grok-build.js +360 -0
  49. package/dist/runners/grok-build.js.map +1 -0
  50. package/dist/runners/grok-build.test.d.ts +1 -0
  51. package/dist/runners/grok-build.test.js +233 -0
  52. package/dist/runners/grok-build.test.js.map +1 -0
  53. package/dist/runners/index.js +3 -0
  54. package/dist/runners/index.js.map +1 -1
  55. package/dist/runners/index.test.js +2 -0
  56. package/dist/runners/index.test.js.map +1 -1
  57. package/dist/runners/kimi-cli.js +2 -8
  58. package/dist/runners/kimi-cli.js.map +1 -1
  59. package/dist/runners/kimi-cli.test.js +8 -0
  60. package/dist/runners/kimi-cli.test.js.map +1 -1
  61. package/dist/runners/kiro-cli.js +2 -8
  62. package/dist/runners/kiro-cli.js.map +1 -1
  63. package/dist/runners/kiro-cli.test.js +1 -0
  64. package/dist/runners/kiro-cli.test.js.map +1 -1
  65. package/dist/runners/log-merger.d.ts +8 -0
  66. package/dist/runners/log-merger.js +33 -0
  67. package/dist/runners/log-merger.js.map +1 -0
  68. package/dist/runners/log-reporter.d.ts +2 -2
  69. package/dist/runners/log-reporter.js +2 -29
  70. package/dist/runners/log-reporter.js.map +1 -1
  71. package/dist/runners/opencode.js +3 -16
  72. package/dist/runners/opencode.js.map +1 -1
  73. package/dist/runners/session-env.d.ts +24 -0
  74. package/dist/runners/session-env.js +61 -0
  75. package/dist/runners/session-env.js.map +1 -0
  76. package/dist/runners/session-env.test.d.ts +1 -0
  77. package/dist/runners/session-env.test.js +78 -0
  78. package/dist/runners/session-env.test.js.map +1 -0
  79. package/dist/runners/stream-json-parser.js +45 -0
  80. package/dist/runners/stream-json-parser.js.map +1 -1
  81. package/dist/runners/types.d.ts +2 -0
  82. package/dist/utils/auto-update.d.ts +17 -2
  83. package/dist/utils/auto-update.js +165 -52
  84. package/dist/utils/auto-update.js.map +1 -1
  85. package/dist/utils/auto-update.test.js +357 -7
  86. package/dist/utils/auto-update.test.js.map +1 -1
  87. package/dist/utils/engine-probe.d.ts +15 -0
  88. package/dist/utils/engine-probe.js +52 -0
  89. package/dist/utils/engine-probe.js.map +1 -0
  90. package/dist/utils/engine-probe.test.d.ts +1 -0
  91. package/dist/utils/engine-probe.test.js +108 -0
  92. package/dist/utils/engine-probe.test.js.map +1 -0
  93. package/dist/utils/model-enumerator.d.ts +42 -0
  94. package/dist/utils/model-enumerator.js +223 -0
  95. package/dist/utils/model-enumerator.js.map +1 -0
  96. package/dist/utils/model-enumerator.test.d.ts +1 -0
  97. package/dist/utils/model-enumerator.test.js +132 -0
  98. package/dist/utils/model-enumerator.test.js.map +1 -0
  99. package/dist/utils/npm-global-permission.d.ts +18 -0
  100. package/dist/utils/npm-global-permission.js +41 -0
  101. package/dist/utils/npm-global-permission.js.map +1 -0
  102. package/dist/utils/npm-global-permission.test.d.ts +1 -0
  103. package/dist/utils/npm-global-permission.test.js +75 -0
  104. package/dist/utils/npm-global-permission.test.js.map +1 -0
  105. package/dist/utils/npm-install-error.d.ts +12 -0
  106. package/dist/utils/npm-install-error.js +19 -0
  107. package/dist/utils/npm-install-error.js.map +1 -0
  108. package/dist/utils/npm-install-error.test.d.ts +1 -0
  109. package/dist/utils/npm-install-error.test.js +28 -0
  110. package/dist/utils/npm-install-error.test.js.map +1 -0
  111. package/native/bin/win32-x64/agentrunner-launcher.exe +0 -0
  112. package/native/bin/win32-x64/manifest.json +2 -2
  113. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  import { test } from 'node:test';
2
2
  import assert from 'node:assert/strict';
3
3
  import { maybeAutoUpdate, resetAutoUpdateState } from './auto-update.js';
4
- test('maybeAutoUpdate calls onRunnerUpdated after successful install', async () => {
4
+ test('maybeAutoUpdate calls onUpdateSucceeded after successful install', async () => {
5
5
  resetAutoUpdateState();
6
6
  let installCalled = false;
7
7
  let notifiedVersion = null;
@@ -18,8 +18,9 @@ test('maybeAutoUpdate calls onRunnerUpdated after successful install', async ()
18
18
  error: () => { },
19
19
  },
20
20
  now: () => Date.now(),
21
- onRunnerUpdated: async (version) => {
22
- notifiedVersion = version;
21
+ canWriteGlobalNpmRoot: () => true,
22
+ onUpdateSucceeded: async (input) => {
23
+ notifiedVersion = input.version;
23
24
  },
24
25
  };
25
26
  const meta = {
@@ -28,9 +29,9 @@ test('maybeAutoUpdate calls onRunnerUpdated after successful install', async ()
28
29
  };
29
30
  await maybeAutoUpdate(meta, deps);
30
31
  assert.ok(installCalled, 'installPackage should be called');
31
- assert.equal(notifiedVersion, '99.9.9', 'onRunnerUpdated should be called with new version');
32
+ assert.equal(notifiedVersion, '99.9.9', 'onUpdateSucceeded should be called with new version');
32
33
  });
33
- test('maybeAutoUpdate does not call onRunnerUpdated again if it already succeeded for that version', async () => {
34
+ test('maybeAutoUpdate does not call onUpdateSucceeded again if it already succeeded for that version', async () => {
34
35
  resetAutoUpdateState();
35
36
  let installCount = 0;
36
37
  let notifyCount = 0;
@@ -45,7 +46,8 @@ test('maybeAutoUpdate does not call onRunnerUpdated again if it already succeede
45
46
  error: () => { },
46
47
  },
47
48
  now: () => Date.now(),
48
- onRunnerUpdated: async () => {
49
+ canWriteGlobalNpmRoot: () => true,
50
+ onUpdateSucceeded: async () => {
49
51
  notifyCount++;
50
52
  },
51
53
  };
@@ -62,6 +64,84 @@ test('maybeAutoUpdate does not call onRunnerUpdated again if it already succeede
62
64
  assert.equal(installCount, 1, 'should not install again');
63
65
  assert.equal(notifyCount, 1, 'should not notify again');
64
66
  });
67
+ /**
68
+ * 실측 재현 로그(리눅스 systemd --user, npm prefix -g = /usr/local):
69
+ * `npm install -g` 자식 프로세스가 EACCES(errno -13)로 죽는다.
70
+ */
71
+ const EACCES_INSTALL_ERROR_MESSAGE = [
72
+ 'Command failed: /usr/bin/npm install -g @agentteams/runner@99.9.9',
73
+ 'npm ERR! code EACCES',
74
+ 'npm ERR! syscall rename',
75
+ 'npm ERR! path /usr/local/lib/node_modules/@agentteams/runner',
76
+ 'npm ERR! errno -13',
77
+ ].join('\n');
78
+ test('maybeAutoUpdate reports EACCES install failure as PERMISSION_DENIED exactly once', async () => {
79
+ resetAutoUpdateState();
80
+ const failures = [];
81
+ const deps = {
82
+ runExecutableSync: (name, args) => {
83
+ if (name === 'npm' && args[0] === 'install') {
84
+ throw new Error(EACCES_INSTALL_ERROR_MESSAGE);
85
+ }
86
+ return '';
87
+ },
88
+ logger: {
89
+ info: () => { },
90
+ warn: () => { },
91
+ error: () => { },
92
+ },
93
+ now: () => 20000000,
94
+ // 프리플라이트는 통과시키고 설치 자체가 EACCES로 죽는 경로를 재현한다.
95
+ canWriteGlobalNpmRoot: () => true,
96
+ onUpdateFailed: async (input) => {
97
+ failures.push(input);
98
+ },
99
+ };
100
+ const meta = {
101
+ cliLatestVersion: null,
102
+ runnerLatestVersion: '99.9.9',
103
+ };
104
+ await maybeAutoUpdate(meta, deps);
105
+ assert.equal(failures.length, 1, 'onUpdateFailed should be called exactly once');
106
+ assert.equal(failures[0]?.package, 'runner');
107
+ assert.equal(failures[0]?.version, '99.9.9');
108
+ assert.equal(failures[0]?.reason, 'PERMISSION_DENIED');
109
+ });
110
+ test('maybeAutoUpdate does not retry a permission-blocked install within 24 hours', async () => {
111
+ resetAutoUpdateState();
112
+ let installCount = 0;
113
+ let failureCount = 0;
114
+ const deps = {
115
+ runExecutableSync: (name, args) => {
116
+ if (name === 'npm' && args[0] === 'install') {
117
+ installCount++;
118
+ throw new Error(EACCES_INSTALL_ERROR_MESSAGE);
119
+ }
120
+ return '';
121
+ },
122
+ logger: {
123
+ info: () => { },
124
+ warn: () => { },
125
+ error: () => { },
126
+ },
127
+ now: () => 20000000,
128
+ canWriteGlobalNpmRoot: () => true,
129
+ onUpdateFailed: async () => {
130
+ failureCount++;
131
+ },
132
+ };
133
+ const meta = {
134
+ cliLatestVersion: null,
135
+ runnerLatestVersion: '99.9.9',
136
+ };
137
+ await maybeAutoUpdate(meta, deps);
138
+ assert.equal(installCount, 1, 'first poll should attempt the install');
139
+ assert.equal(failureCount, 1, 'first poll should report the failure');
140
+ // 기존 1시간 쿨다운은 지났지만 권한 차단 백오프(24시간) 안이므로 재시도하지 않는다.
141
+ await maybeAutoUpdate(meta, { ...deps, now: () => 20000000 + 2 * 60 * 60 * 1000 });
142
+ assert.equal(installCount, 1, 'should not retry install within the permission-blocked backoff');
143
+ assert.equal(failureCount, 1, 'should not report the same failure again');
144
+ });
65
145
  test('maybeAutoUpdate RETRIES notification if it failed before', async () => {
66
146
  resetAutoUpdateState();
67
147
  let notifyCount = 0;
@@ -74,7 +154,8 @@ test('maybeAutoUpdate RETRIES notification if it failed before', async () => {
74
154
  error: () => { },
75
155
  },
76
156
  now: () => 10000000,
77
- onRunnerUpdated: async () => {
157
+ canWriteGlobalNpmRoot: () => true,
158
+ onUpdateSucceeded: async () => {
78
159
  if (shouldFailNotify) {
79
160
  shouldFailNotify = false;
80
161
  throw new Error('Network error');
@@ -97,4 +178,273 @@ test('maybeAutoUpdate RETRIES notification if it failed before', async () => {
97
178
  console.log('Second call done. notifyCount:', notifyCount);
98
179
  assert.equal(notifyCount, 1, 'Should retry notification successfully');
99
180
  });
181
+ test('maybeAutoUpdate skips the install entirely when the global npm root is not writable', async () => {
182
+ resetAutoUpdateState();
183
+ const commands = [];
184
+ const failures = [];
185
+ const warnings = [];
186
+ const deps = {
187
+ runExecutableSync: (name, args) => {
188
+ commands.push({ name, args });
189
+ return '';
190
+ },
191
+ logger: {
192
+ info: () => { },
193
+ warn: (message) => {
194
+ warnings.push(message);
195
+ },
196
+ error: () => { },
197
+ },
198
+ now: () => 30000000,
199
+ canWriteGlobalNpmRoot: () => false,
200
+ onUpdateFailed: async (input) => {
201
+ failures.push(input);
202
+ },
203
+ };
204
+ const meta = {
205
+ cliLatestVersion: null,
206
+ runnerLatestVersion: '99.9.9',
207
+ };
208
+ await maybeAutoUpdate(meta, deps);
209
+ assert.equal(commands.filter((command) => command.name === 'npm' && command.args[0] === 'install').length, 0, 'npm install -g should not run when the preflight says the global npm root is not writable');
210
+ assert.equal(failures.length, 1);
211
+ assert.equal(failures[0]?.reason, 'PERMISSION_DENIED');
212
+ assert.equal(warnings.length, 1, 'the remediation hint should be logged once per target version');
213
+ });
214
+ test('maybeAutoUpdate falls back to attempting the install when the preflight cannot decide', async () => {
215
+ resetAutoUpdateState();
216
+ let installCalled = false;
217
+ const deps = {
218
+ runExecutableSync: (name, args) => {
219
+ if (name === 'npm' && args[0] === 'install') {
220
+ installCalled = true;
221
+ }
222
+ return '';
223
+ },
224
+ logger: {
225
+ info: () => { },
226
+ warn: () => { },
227
+ error: () => { },
228
+ },
229
+ now: () => 40000000,
230
+ canWriteGlobalNpmRoot: () => {
231
+ throw new Error('npm prefix -g failed');
232
+ },
233
+ onUpdateFailed: async () => { },
234
+ };
235
+ const meta = {
236
+ cliLatestVersion: null,
237
+ runnerLatestVersion: '99.9.9',
238
+ };
239
+ await maybeAutoUpdate(meta, deps);
240
+ assert.ok(installCalled, 'fail-open: an undecidable preflight must not block the install');
241
+ });
242
+ test('maybeAutoUpdate retries immediately when the permission-blocked target version changes', async () => {
243
+ resetAutoUpdateState();
244
+ let installCount = 0;
245
+ const failures = [];
246
+ const deps = {
247
+ runExecutableSync: (name, args) => {
248
+ if (name === 'npm' && args[0] === 'install') {
249
+ installCount++;
250
+ throw new Error('npm ERR! code EACCES');
251
+ }
252
+ return '';
253
+ },
254
+ logger: {
255
+ info: () => { },
256
+ warn: () => { },
257
+ error: () => { },
258
+ },
259
+ now: () => 50000000,
260
+ canWriteGlobalNpmRoot: () => true,
261
+ onUpdateFailed: async (input) => {
262
+ failures.push(input);
263
+ },
264
+ };
265
+ await maybeAutoUpdate({ cliLatestVersion: null, runnerLatestVersion: '99.9.9' }, deps);
266
+ assert.equal(installCount, 1);
267
+ // 대상 버전이 바뀌면 24시간 백오프와 무관하게 다시 시도한다(1시간 쿨다운만 적용).
268
+ await maybeAutoUpdate({ cliLatestVersion: null, runnerLatestVersion: '99.9.10' }, { ...deps, now: () => 50000000 + 60 * 60 * 1000 + 1 });
269
+ assert.equal(installCount, 2, 'a new target version should be attempted again');
270
+ assert.deepEqual(failures.map((failure) => failure.version), ['99.9.9', '99.9.10']);
271
+ });
272
+ test('maybeAutoUpdate retries the failure report when the server call failed', async () => {
273
+ resetAutoUpdateState();
274
+ let reportAttempts = 0;
275
+ let shouldFailReport = true;
276
+ const deps = {
277
+ runExecutableSync: () => '',
278
+ logger: {
279
+ info: () => { },
280
+ warn: () => { },
281
+ error: () => { },
282
+ },
283
+ now: () => 60000000,
284
+ canWriteGlobalNpmRoot: () => false,
285
+ onUpdateFailed: async () => {
286
+ reportAttempts++;
287
+ if (shouldFailReport) {
288
+ shouldFailReport = false;
289
+ throw new Error('Network error');
290
+ }
291
+ },
292
+ };
293
+ const meta = {
294
+ cliLatestVersion: null,
295
+ runnerLatestVersion: '99.9.9',
296
+ };
297
+ await maybeAutoUpdate(meta, deps);
298
+ assert.equal(reportAttempts, 1);
299
+ // 보고 실패는 수렴 대상이 아니다. 24시간 백오프가 지난 뒤 다시 보고를 시도한다.
300
+ await maybeAutoUpdate(meta, { ...deps, now: () => 60000000 + 24 * 60 * 60 * 1000 + 1 });
301
+ assert.equal(reportAttempts, 2, 'a failed report should be retried');
302
+ // 보고에 성공했으면 같은 대상 버전으로 다시 보내지 않는다.
303
+ await maybeAutoUpdate(meta, { ...deps, now: () => 60000000 + 48 * 60 * 60 * 1000 + 2 });
304
+ assert.equal(reportAttempts, 2, 'a succeeded report should converge to once per target version');
305
+ });
306
+ test('maybeAutoUpdate retries the failure report on the next poll even while the install is permission-blocked', async () => {
307
+ resetAutoUpdateState();
308
+ let installCount = 0;
309
+ let reportAttempts = 0;
310
+ let shouldFailReport = true;
311
+ const deps = {
312
+ runExecutableSync: (name, args) => {
313
+ if (name === 'npm' && args[0] === 'install') {
314
+ installCount++;
315
+ throw new Error(EACCES_INSTALL_ERROR_MESSAGE);
316
+ }
317
+ return '';
318
+ },
319
+ logger: {
320
+ info: () => { },
321
+ warn: () => { },
322
+ error: () => { },
323
+ },
324
+ now: () => 70000000,
325
+ canWriteGlobalNpmRoot: () => true,
326
+ onUpdateFailed: async () => {
327
+ reportAttempts++;
328
+ if (shouldFailReport) {
329
+ shouldFailReport = false;
330
+ throw new Error('Network error');
331
+ }
332
+ },
333
+ };
334
+ const meta = {
335
+ cliLatestVersion: null,
336
+ runnerLatestVersion: '99.9.9',
337
+ };
338
+ await maybeAutoUpdate(meta, deps);
339
+ assert.equal(installCount, 1);
340
+ assert.equal(reportAttempts, 1, 'the first poll should attempt the report');
341
+ // 설치는 24시간 권한 백오프에 걸려 있어도, 미전송 보고는 바로 다음 폴링에서 재시도된다.
342
+ await maybeAutoUpdate(meta, { ...deps, now: () => 70000000 + 60 * 1000 });
343
+ assert.equal(installCount, 1, 'the install must stay inside the permission-blocked backoff');
344
+ assert.equal(reportAttempts, 2, 'an unsent failure report must be retried on the very next poll');
345
+ // 보고에 성공했으면 같은 (version, reason)으로 다시 보내지 않는다.
346
+ await maybeAutoUpdate(meta, { ...deps, now: () => 70000000 + 2 * 60 * 1000 });
347
+ assert.equal(reportAttempts, 2, 'a succeeded report should converge');
348
+ });
349
+ test('maybeAutoUpdate reports a changed failure reason for the same target version', async () => {
350
+ resetAutoUpdateState();
351
+ const failures = [];
352
+ let installError = new Error('npm ERR! network timeout');
353
+ const deps = {
354
+ runExecutableSync: (name, args) => {
355
+ if (name === 'npm' && args[0] === 'install') {
356
+ throw installError;
357
+ }
358
+ return '';
359
+ },
360
+ logger: {
361
+ info: () => { },
362
+ warn: () => { },
363
+ error: () => { },
364
+ },
365
+ now: () => 80000000,
366
+ canWriteGlobalNpmRoot: () => true,
367
+ onUpdateFailed: async (input) => {
368
+ failures.push(input);
369
+ },
370
+ };
371
+ const meta = {
372
+ cliLatestVersion: null,
373
+ runnerLatestVersion: '99.9.9',
374
+ };
375
+ await maybeAutoUpdate(meta, deps);
376
+ assert.deepEqual(failures.map((failure) => failure.reason), ['UNKNOWN']);
377
+ // 같은 대상 버전이라도 사유가 바뀌면 서버가 새 상태로 취급하므로 다시 보고해야 한다.
378
+ installError = new Error(EACCES_INSTALL_ERROR_MESSAGE);
379
+ await maybeAutoUpdate(meta, { ...deps, now: () => 80000000 + 60 * 60 * 1000 + 1 });
380
+ assert.deepEqual(failures.map((failure) => failure.reason), ['UNKNOWN', 'PERMISSION_DENIED']);
381
+ // 완전히 동일한 (version, reason)만 억제된다.
382
+ await maybeAutoUpdate(meta, { ...deps, now: () => 80000000 + 25 * 60 * 60 * 1000 });
383
+ assert.equal(failures.length, 2, 'an identical (version, reason) report must be suppressed');
384
+ });
385
+ test('maybeAutoUpdate attempts a new target version immediately after a permission failure', async () => {
386
+ resetAutoUpdateState();
387
+ const attemptedVersions = [];
388
+ const deps = {
389
+ runExecutableSync: (name, args) => {
390
+ if (name === 'npm' && args[0] === 'install') {
391
+ attemptedVersions.push(String(args[2]));
392
+ throw new Error(EACCES_INSTALL_ERROR_MESSAGE);
393
+ }
394
+ return '';
395
+ },
396
+ logger: {
397
+ info: () => { },
398
+ warn: () => { },
399
+ error: () => { },
400
+ },
401
+ now: () => 90000000,
402
+ canWriteGlobalNpmRoot: () => true,
403
+ onUpdateFailed: async () => { },
404
+ };
405
+ await maybeAutoUpdate({ cliLatestVersion: null, runnerLatestVersion: '99.9.9' }, deps);
406
+ assert.deepEqual(attemptedVersions, ['@agentteams/runner@99.9.9']);
407
+ // 실패 직후 1분 만에 새 버전이 배포되면 쿨다운을 기다리지 않고 즉시 시도한다.
408
+ await maybeAutoUpdate({ cliLatestVersion: null, runnerLatestVersion: '99.9.10' }, { ...deps, now: () => 90000000 + 60 * 1000 });
409
+ assert.deepEqual(attemptedVersions, ['@agentteams/runner@99.9.9', '@agentteams/runner@99.9.10']);
410
+ });
411
+ test('maybeAutoUpdate reports a CLI install success so the server can clear the CLI failure', async () => {
412
+ resetAutoUpdateState();
413
+ const successes = [];
414
+ const failures = [];
415
+ let canWrite = false;
416
+ const deps = {
417
+ runExecutableSync: (name, args) => {
418
+ if (name === 'npm' && args[0] === 'list') {
419
+ return JSON.stringify({ dependencies: { '@agentteams/cli': { version: '1.0.0' } } });
420
+ }
421
+ return '';
422
+ },
423
+ logger: {
424
+ info: () => { },
425
+ warn: () => { },
426
+ error: () => { },
427
+ },
428
+ now: () => 100000000,
429
+ canWriteGlobalNpmRoot: () => canWrite,
430
+ onUpdateSucceeded: async (input) => {
431
+ successes.push(input);
432
+ },
433
+ onUpdateFailed: async (input) => {
434
+ failures.push(input);
435
+ },
436
+ };
437
+ const meta = {
438
+ cliLatestVersion: '1.1.0',
439
+ runnerLatestVersion: null,
440
+ };
441
+ await maybeAutoUpdate(meta, deps);
442
+ assert.equal(failures.length, 1, 'the blocked CLI install should be reported');
443
+ assert.equal(failures[0]?.package, 'cli');
444
+ assert.equal(successes.length, 0);
445
+ // 사용자가 권한을 고친 뒤 새 대상 버전이 나오면 즉시 재시도되고, 성공은 패키지와 함께 보고된다.
446
+ canWrite = true;
447
+ await maybeAutoUpdate({ cliLatestVersion: '1.1.1', runnerLatestVersion: null }, { ...deps, canWriteGlobalNpmRoot: () => canWrite, now: () => 100000000 + 60 * 1000 });
448
+ assert.deepEqual(successes, [{ package: 'cli', version: '1.1.1' }]);
449
+ });
100
450
  //# sourceMappingURL=auto-update.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"auto-update.test.js","sourceRoot":"","sources":["../../src/utils/auto-update.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAEzE,IAAI,CAAC,gEAAgE,EAAE,KAAK,IAAI,EAAE;IAChF,oBAAoB,EAAE,CAAC;IAEvB,IAAI,aAAa,GAAG,KAAK,CAAC;IAC1B,IAAI,eAAe,GAAkB,IAAI,CAAC;IAE1C,MAAM,IAAI,GAAG;QACX,iBAAiB,EAAE,CAAC,IAAY,EAAE,IAAc,EAAE,EAAE;YAClD,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;gBAC5C,aAAa,GAAG,IAAI,CAAC;YACvB,CAAC;YACD,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,MAAM,EAAE;YACN,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC;YACd,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC;YACd,KAAK,EAAE,GAAG,EAAE,GAAE,CAAC;SAChB;QACD,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;QACrB,eAAe,EAAE,KAAK,EAAE,OAAe,EAAE,EAAE;YACzC,eAAe,GAAG,OAAO,CAAC;QAC5B,CAAC;KACF,CAAC;IAEF,MAAM,IAAI,GAAG;QACX,gBAAgB,EAAE,IAAI;QACtB,mBAAmB,EAAE,QAAQ;KAC9B,CAAC;IAEF,MAAM,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAElC,MAAM,CAAC,EAAE,CAAC,aAAa,EAAE,iCAAiC,CAAC,CAAC;IAC5D,MAAM,CAAC,KAAK,CAAC,eAAe,EAAE,QAAQ,EAAE,mDAAmD,CAAC,CAAC;AAC/F,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,8FAA8F,EAAE,KAAK,IAAI,EAAE;IAC9G,oBAAoB,EAAE,CAAC;IAEvB,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,IAAI,WAAW,GAAG,CAAC,CAAC;IAEpB,MAAM,IAAI,GAAG;QACX,iBAAiB,EAAE,GAAG,EAAE;YACtB,YAAY,EAAE,CAAC;YACf,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,MAAM,EAAE;YACN,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC;YACd,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC;YACd,KAAK,EAAE,GAAG,EAAE,GAAE,CAAC;SAChB;QACD,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;QACrB,eAAe,EAAE,KAAK,IAAI,EAAE;YAC1B,WAAW,EAAE,CAAC;QAChB,CAAC;KACF,CAAC;IAEF,MAAM,IAAI,GAAG;QACX,gBAAgB,EAAE,IAAI;QACtB,mBAAmB,EAAE,QAAQ;KAC9B,CAAC;IAEF,aAAa;IACb,MAAM,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAClC,MAAM,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;IAC9B,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IAE7B,gCAAgC;IAChC,MAAM,eAAe,CAAC,IAAI,EAAE,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC;IACrF,MAAM,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC,EAAE,0BAA0B,CAAC,CAAC;IAC1D,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,EAAE,yBAAyB,CAAC,CAAC;AAC1D,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,0DAA0D,EAAE,KAAK,IAAI,EAAE;IAC1E,oBAAoB,EAAE,CAAC;IAEvB,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,IAAI,gBAAgB,GAAG,IAAI,CAAC;IAE5B,MAAM,IAAI,GAAG;QACX,iBAAiB,EAAE,GAAG,EAAE,CAAC,EAAE;QAC3B,MAAM,EAAE;YACN,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC;YACd,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC;YACd,KAAK,EAAE,GAAG,EAAE,GAAE,CAAC;SAChB;QACD,GAAG,EAAE,GAAG,EAAE,CAAC,QAAQ;QACnB,eAAe,EAAE,KAAK,IAAI,EAAE;YAC1B,IAAI,gBAAgB,EAAE,CAAC;gBACrB,gBAAgB,GAAG,KAAK,CAAC;gBACzB,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;YACnC,CAAC;YACD,WAAW,EAAE,CAAC;QAChB,CAAC;KACF,CAAC;IAEF,MAAM,IAAI,GAAG;QACX,gBAAgB,EAAE,IAAI;QACtB,mBAAmB,EAAE,QAAQ;KAC9B,CAAC;IAEF,mDAAmD;IACnD,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;IACtC,MAAM,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAClC,OAAO,CAAC,GAAG,CAAC,+BAA+B,EAAE,WAAW,CAAC,CAAC;IAC1D,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,EAAE,iCAAiC,CAAC,CAAC;IAEhE,8BAA8B;IAC9B,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;IACvC,MAAM,eAAe,CAAC,IAAI,EAAE,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,QAAQ,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC;IACnF,OAAO,CAAC,GAAG,CAAC,gCAAgC,EAAE,WAAW,CAAC,CAAC;IAE3D,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,EAAE,wCAAwC,CAAC,CAAC;AACzE,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"auto-update.test.js","sourceRoot":"","sources":["../../src/utils/auto-update.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { RunnerType } from '@agentteams/core-constants';
2
+ import { getNpmGlobalBinPathAsync, isExecutableLookupAvailable, resolveExecutablePathWithPreferenceAsync, resolveExecutablePathsWithPreferenceAsync, runProbeCommand, type AsyncExecutableDeps } from '../executable.js';
3
+ type EngineProbeDependencies = AsyncExecutableDeps & {
4
+ getNpmGlobalBinPathAsync?: typeof getNpmGlobalBinPathAsync;
5
+ resolveExecutablePathWithPreferenceAsync?: typeof resolveExecutablePathWithPreferenceAsync;
6
+ resolveExecutablePathsWithPreferenceAsync?: typeof resolveExecutablePathsWithPreferenceAsync;
7
+ isExecutableLookupAvailable?: typeof isExecutableLookupAvailable;
8
+ runProbeCommand?: typeof runProbeCommand;
9
+ };
10
+ export type EngineProbeResult = {
11
+ engines: RunnerType[];
12
+ reliable: boolean;
13
+ };
14
+ export declare const probeInstalledEngines: (runnerCmd: string, deps?: EngineProbeDependencies) => Promise<EngineProbeResult>;
15
+ export {};
@@ -0,0 +1,52 @@
1
+ import { getNpmGlobalBinPathAsync, isExecutableLookupAvailable, resolveExecutablePathWithPreferenceAsync, runProbeCommand, } from '../executable.js';
2
+ import { ENGINE_COMMANDS, getEngineCommand, getEngineExecutablePreference } from '../runners/engine-commands.js';
3
+ import { findGrokBuildExecutable } from '../runners/grok-build-identity.js';
4
+ const isCursorAgent = async (executablePath, run, deps) => {
5
+ const output = await run(executablePath, ['--help'], deps);
6
+ return output !== null && output.includes('Start the Cursor Agent');
7
+ };
8
+ export const probeInstalledEngines = async (runnerCmd, deps = {}) => {
9
+ const resolve = deps.resolveExecutablePathWithPreferenceAsync ?? resolveExecutablePathWithPreferenceAsync;
10
+ const resolveNpmGlobalBin = deps.getNpmGlobalBinPathAsync ?? getNpmGlobalBinPathAsync;
11
+ const checkLookupAvailable = deps.isExecutableLookupAvailable ?? isExecutableLookupAvailable;
12
+ const runCommand = deps.runProbeCommand ?? runProbeCommand;
13
+ const isWindows = (deps.platform ?? (() => process.platform))() === 'win32';
14
+ const executableDeps = {
15
+ ...deps,
16
+ // 미설치 엔진마다 `npm prefix -g`를 반복하지 않도록 프로브 사이클에서 한 번만 계산한다.
17
+ npmGlobalBinPath: await resolveNpmGlobalBin(deps),
18
+ };
19
+ const engines = [];
20
+ for (const runnerType of Object.keys(ENGINE_COMMANDS)) {
21
+ if (runnerType === 'GROK_BUILD') {
22
+ const preferredNames = getEngineExecutablePreference(runnerType, runnerCmd, isWindows);
23
+ const grokDependencies = deps.resolveExecutablePathWithPreferenceAsync && !deps.resolveExecutablePathsWithPreferenceAsync
24
+ ? {
25
+ ...executableDeps,
26
+ runProbeCommand: runCommand,
27
+ resolveExecutablePathsWithPreferenceAsync: async (name, preference) => {
28
+ const candidate = await resolve(name, preference, executableDeps);
29
+ return candidate ? [candidate] : [];
30
+ },
31
+ }
32
+ : { ...executableDeps, runProbeCommand: runCommand };
33
+ if (await findGrokBuildExecutable(preferredNames, grokDependencies))
34
+ engines.push(runnerType);
35
+ continue;
36
+ }
37
+ const executablePath = await resolve(getEngineCommand(runnerType, runnerCmd), getEngineExecutablePreference(runnerType, runnerCmd, isWindows), executableDeps);
38
+ if (!executablePath) {
39
+ continue;
40
+ }
41
+ // `agent`는 일반적인 이름이므로 Cursor 고유 help 문구까지 확인해 오탐을 막는다.
42
+ if (runnerType === 'CURSOR_CLI' && !(await isCursorAgent(executablePath, runCommand, deps))) {
43
+ continue;
44
+ }
45
+ engines.push(runnerType);
46
+ }
47
+ // 하나라도 찾았으면 조회 자체는 동작한 것이다. 0개일 때만 조회 명령의 가용성을 따져
48
+ // "설치 0개"와 "탐지 실패"를 구분한다.
49
+ const reliable = engines.length > 0 || (await checkLookupAvailable(deps));
50
+ return { engines, reliable };
51
+ };
52
+ //# sourceMappingURL=engine-probe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine-probe.js","sourceRoot":"","sources":["../../src/utils/engine-probe.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,108 @@
1
+ import assert from 'node:assert/strict';
2
+ import { describe, it } from 'node:test';
3
+ import { probeInstalledEngines } from './engine-probe.js';
4
+ describe('probeInstalledEngines', () => {
5
+ it('returns only installed engines and resolves npm global bin once per cycle', async () => {
6
+ let npmGlobalBinCalls = 0;
7
+ const result = await probeInstalledEngines('custom-opencode', {
8
+ getNpmGlobalBinPathAsync: async () => {
9
+ npmGlobalBinCalls += 1;
10
+ return '/global/bin';
11
+ },
12
+ resolveExecutablePathWithPreferenceAsync: async (name, _preferredNames, deps) => {
13
+ assert.equal(deps?.npmGlobalBinPath, '/global/bin');
14
+ return name === 'codex' ? '/bin/codex' : null;
15
+ },
16
+ });
17
+ assert.deepEqual(result.engines, ['CODEX']);
18
+ assert.equal(result.reliable, true);
19
+ assert.equal(npmGlobalBinCalls, 1);
20
+ });
21
+ it('uses the configured OpenCode command and absorbs individual probe failures', async () => {
22
+ const requestedCommands = [];
23
+ const result = await probeInstalledEngines('custom-opencode', {
24
+ getNpmGlobalBinPathAsync: async () => null,
25
+ resolveExecutablePathWithPreferenceAsync: async (name) => {
26
+ requestedCommands.push(name);
27
+ return name === 'custom-opencode' ? '/bin/custom-opencode' : null;
28
+ },
29
+ });
30
+ assert.equal(requestedCommands[0], 'custom-opencode');
31
+ assert.deepEqual(result.engines, ['OPENCODE']);
32
+ });
33
+ // 탐지와 실제 기동이 갈리지 않도록 러너 모듈과 같은 선호 목록을 넘겨야 한다.
34
+ it('passes the same executable preference the runners use', async () => {
35
+ const preferences = new Map();
36
+ await probeInstalledEngines('opencode', {
37
+ platform: () => 'win32',
38
+ getNpmGlobalBinPathAsync: async () => null,
39
+ resolveExecutablePathWithPreferenceAsync: async (name, preferredNames) => {
40
+ preferences.set(name, preferredNames);
41
+ return null;
42
+ },
43
+ });
44
+ assert.deepEqual(preferences.get('claude'), ['claude.cmd', 'claude']);
45
+ assert.deepEqual(preferences.get('kimi'), ['kimi.cmd', 'kimi']);
46
+ assert.deepEqual(preferences.get('kiro-cli'), ['kiro-cli.exe', 'kiro-cli']);
47
+ assert.deepEqual(preferences.get('agent'), ['agent']);
48
+ assert.deepEqual(preferences.get('grok'), ['grok.exe', 'grok']);
49
+ });
50
+ it('accepts Cursor only when the executable identifies itself as Cursor Agent', async () => {
51
+ const probe = (helpText) => probeInstalledEngines('opencode', {
52
+ getNpmGlobalBinPathAsync: async () => null,
53
+ runProbeCommand: async () => helpText,
54
+ resolveExecutablePathWithPreferenceAsync: async (name) => (name === 'agent' ? '/bin/agent' : null),
55
+ });
56
+ assert.deepEqual((await probe('Start the Cursor Agent')).engines, ['CURSOR_CLI']);
57
+ assert.deepEqual((await probe('Unrelated agent utility')).engines, []);
58
+ // 타임아웃으로 죽은 --help는 null을 돌려주며, 오탐 대신 미설치로 취급한다.
59
+ assert.deepEqual((await probe(null)).engines, []);
60
+ });
61
+ // `grok`은 무관한 npm 패키지(@vibe-kit/grok-cli)도 쓰는 이름이라, 공식 help 문구가 없으면
62
+ // 설치된 것으로 보고하면 안 된다. 서드파티를 GROK_BUILD로 오탐하면 실행이 통째로 깨진다.
63
+ it('accepts Grok only when the executable identifies itself as Grok Build', async () => {
64
+ const probe = (helpText) => probeInstalledEngines('opencode', {
65
+ getNpmGlobalBinPathAsync: async () => null,
66
+ runProbeCommand: async () => helpText,
67
+ resolveExecutablePathWithPreferenceAsync: async (name) => (name === 'grok' ? '/bin/grok' : null),
68
+ });
69
+ assert.deepEqual((await probe('Grok Build TUI\n\nUsage: grok [OPTIONS] [PROMPT]')).engines, ['GROK_BUILD']);
70
+ // 서드파티 @vibe-kit/grok-cli의 help에는 이 문구가 없다.
71
+ assert.deepEqual((await probe('Grok CLI - AI assistant in your terminal')).engines, []);
72
+ assert.deepEqual((await probe(null)).engines, []);
73
+ });
74
+ it('skips a conflicting Grok candidate and accepts the next official installation', async () => {
75
+ const probed = [];
76
+ const result = await probeInstalledEngines('opencode', {
77
+ getNpmGlobalBinPathAsync: async () => null,
78
+ resolveExecutablePathsWithPreferenceAsync: async (name) => name === 'grok' ? ['/custom/bin/grok', '/usr/local/bin/grok'] : [],
79
+ resolveExecutablePathWithPreferenceAsync: async () => null,
80
+ runProbeCommand: async (executablePath) => {
81
+ probed.push(executablePath);
82
+ return executablePath === '/usr/local/bin/grok' ? 'Grok Build TUI' : 'Grok CLI - AI assistant';
83
+ },
84
+ });
85
+ assert.deepEqual(probed, ['/custom/bin/grok', '/usr/local/bin/grok']);
86
+ assert.deepEqual(result.engines, ['GROK_BUILD']);
87
+ });
88
+ // 빈 목록은 서버에서 "제한 없음"으로 해석되므로, 조회 자체가 불가능한 환경은 보고 대상에서 빼야 한다.
89
+ it('marks a zero-engine result unreliable when the lookup command cannot run', async () => {
90
+ const result = await probeInstalledEngines('opencode', {
91
+ getNpmGlobalBinPathAsync: async () => null,
92
+ resolveExecutablePathWithPreferenceAsync: async () => null,
93
+ isExecutableLookupAvailable: async () => false,
94
+ });
95
+ assert.deepEqual(result.engines, []);
96
+ assert.equal(result.reliable, false);
97
+ });
98
+ it('keeps a zero-engine result reliable when the lookup command works', async () => {
99
+ const result = await probeInstalledEngines('opencode', {
100
+ getNpmGlobalBinPathAsync: async () => null,
101
+ resolveExecutablePathWithPreferenceAsync: async () => null,
102
+ isExecutableLookupAvailable: async () => true,
103
+ });
104
+ assert.deepEqual(result.engines, []);
105
+ assert.equal(result.reliable, true);
106
+ });
107
+ });
108
+ //# sourceMappingURL=engine-probe.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine-probe.test.js","sourceRoot":"","sources":["../../src/utils/engine-probe.test.ts"],"names":[],"mappings":"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"}