( isNonInteractiveSession: boolean, )
| 536 | } |
| 537 | |
| 538 | async function _executeApiKeyHelper( |
| 539 | isNonInteractiveSession: boolean, |
| 540 | ): Promise<string | null> { |
| 541 | const apiKeyHelper = getConfiguredApiKeyHelper() |
| 542 | if (!apiKeyHelper) { |
| 543 | return null |
| 544 | } |
| 545 | |
| 546 | if (isApiKeyHelperFromProjectOrLocalSettings()) { |
| 547 | const hasTrust = checkHasTrustDialogAccepted() |
| 548 | if (!hasTrust && !isNonInteractiveSession) { |
| 549 | const error = new Error( |
| 550 | `Security: apiKeyHelper executed before workspace trust is confirmed. If you see this message, post in ${MACRO.FEEDBACK_CHANNEL}.`, |
| 551 | ) |
| 552 | logAntError('apiKeyHelper invoked before trust check', error) |
| 553 | logEvent('tengu_apiKeyHelper_missing_trust11', {}) |
| 554 | return null |
| 555 | } |
| 556 | } |
| 557 | |
| 558 | const result = await execa(apiKeyHelper, { |
| 559 | shell: true, |
| 560 | timeout: 10 * 60 * 1000, |
| 561 | reject: false, |
| 562 | }) |
| 563 | if (result.failed) { |
| 564 | // reject:false — execa resolves on exit≠0/timeout, stderr is on result |
| 565 | const why = result.timedOut ? 'timed out' : `exited ${result.exitCode}` |
| 566 | const stderr = result.stderr?.trim() |
| 567 | throw new Error(stderr ? `${why}: ${stderr}` : why) |
| 568 | } |
| 569 | const stdout = result.stdout?.trim() |
| 570 | if (!stdout) { |
| 571 | throw new Error('did not return a value') |
| 572 | } |
| 573 | return stdout |
| 574 | } |
| 575 | |
| 576 | /** |
| 577 | * Sync cache reader — returns the last fetched apiKeyHelper value without executing. |
no test coverage detected