From a4083152fcae20427926122e08e3d171c2f9dc39 Mon Sep 17 00:00:00 2001 From: Nas Kavian Date: Sat, 5 Sep 2026 15:25:23 -0700 Subject: [PATCH] fix(cli): start vault daemon for status commands --- .changeset/bright-vault-status.md | 5 +++++ packages/cli/src/startup-vault.ts | 5 ++++- packages/cli/test/unit/startup-vault.test.ts | 4 +++- 3 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 .changeset/bright-vault-status.md diff --git a/.changeset/bright-vault-status.md b/.changeset/bright-vault-status.md new file mode 100644 index 0000000..136e012 --- /dev/null +++ b/.changeset/bright-vault-status.md @@ -0,0 +1,5 @@ +--- +'@inflowpayai/inflow': patch +--- + +Start the local vault daemon before reporting authentication or vault status. diff --git a/packages/cli/src/startup-vault.ts b/packages/cli/src/startup-vault.ts index 3f39b56..b1e6c81 100644 --- a/packages/cli/src/startup-vault.ts +++ b/packages/cli/src/startup-vault.ts @@ -48,7 +48,10 @@ export function normalizeFormatAssignments(argv: string[]): void { export function shouldStartVaultDaemon(argv: readonly string[], hasDirectApiKey = false): boolean { if (shouldBypassVault(argv)) return false; const [group, subcommand] = commandPath(argv); - if (group === 'auth') return subcommand === 'login' || subcommand === 'logout'; + if (group === 'auth') { + return isOneOf(subcommand, 'login', 'logout') || (!hasDirectApiKey && subcommand === 'status'); + } + if (group === 'vault') return subcommand === 'status'; if (group === 'aep') return isOneOf(subcommand, 'enroll', 'fetch', 'grant', 'revoke', 'status'); if (group === 'odp') return shouldConfigureOdpServiceTransport(argv); if (group === 'mpp') { diff --git a/packages/cli/test/unit/startup-vault.test.ts b/packages/cli/test/unit/startup-vault.test.ts index a80a0cc..6090494 100644 --- a/packages/cli/test/unit/startup-vault.test.ts +++ b/packages/cli/test/unit/startup-vault.test.ts @@ -63,7 +63,7 @@ describe('vault startup decisions', () => { it.each([ ['auth login', ['auth', 'login'], true], ['auth logout', ['auth', 'logout'], true], - ['auth status', ['auth', 'status'], false], + ['auth status', ['auth', 'status'], true], ['aep enroll', ['aep', 'enroll'], true], ['aep fetch', ['aep', 'fetch'], true], ['aep grant', ['aep', 'grant'], true], @@ -91,6 +91,7 @@ describe('vault startup decisions', () => { ['subscriptions list', ['subscriptions', 'list'], false], ['subscriptions fetch', ['subscriptions', 'fetch', 'id', 'https://seller.test'], true], ['user get', ['user', 'get'], false], + ['vault status', ['vault', 'status'], true], ['vault unlock', ['vault', 'unlock'], false], ['top inspect', ['inspect'], false], ] as const)('starts daemon for %s when required', (_label, args, expected) => { @@ -184,6 +185,7 @@ describe('vault startup decisions', () => { it('bypasses vault credentials that a direct InFlow API key replaces', () => { expect(shouldStartVaultDaemon(argv('mpp', 'pay'), true)).toBe(false); + expect(shouldStartVaultDaemon(argv('auth', 'status'), true)).toBe(false); expect(shouldReconcileVaultDaemon(argv('balances', 'list'), true)).toBe(false); expect(shouldReconcileVaultDaemon(argv('auth', 'status'), true)).toBe(false); expect(shouldUnlockVault(argv('x402', 'fetch'), { hasDirectApiKey: true })).toBe(false);