@ouro.bot/cli 0.1.0-alpha.419 → 0.1.0-alpha.420

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/changelog.json CHANGED
@@ -1,6 +1,15 @@
1
1
  {
2
2
  "_note": "This changelog is maintained as part of the PR/version-bump workflow. Agent-curated, not auto-generated. Agents read this file directly via read_file to understand what changed between versions.",
3
3
  "versions": [
4
+ {
5
+ "version": "0.1.0-alpha.420",
6
+ "changes": [
7
+ "`ouro auth verify`, `ouro use`, and `ouro provider check` now share the human CLI progress checklist, so vault reads and live provider pings show visible phases instead of leaving a blinking cursor.",
8
+ "`ouro repair` provider-auth actions now reuse the same `ouro auth` runner/progress path, keeping browser/token repair flows consistent with direct auth commands.",
9
+ "Provider credential reads now accept the shared progress callback, letting command surfaces show vault-read detail without duplicating vault logic or exposing secrets.",
10
+ "`@ouro.bot/cli` and the `ouro.bot` wrapper are version-synced for the provider verification progress release."
11
+ ]
12
+ },
4
13
  {
5
14
  "version": "0.1.0-alpha.419",
6
15
  "changes": [
@@ -1513,8 +1513,8 @@ function pingAttemptCount(result) {
1513
1513
  return result.attempts.length;
1514
1514
  return undefined;
1515
1515
  }
1516
- async function readProviderCredentialRecord(agent, provider, _deps) {
1517
- const poolResult = await (0, provider_credentials_1.refreshProviderCredentialPool)(agent);
1516
+ async function readProviderCredentialRecord(agent, provider, _deps, options = {}) {
1517
+ const poolResult = await (0, provider_credentials_1.refreshProviderCredentialPool)(agent, options);
1518
1518
  if (poolResult.ok) {
1519
1519
  const existing = poolResult.pool.providers[provider];
1520
1520
  if (existing)
@@ -1565,18 +1565,55 @@ function writeProviderReadiness(input) {
1565
1565
  (0, provider_state_1.writeProviderState)(input.agentRoot, input.state);
1566
1566
  }
1567
1567
  async function executeProviderUse(command, deps, options = {}) {
1568
+ const progress = options.writeStdout === false ? null : createHumanCommandProgress(deps, "provider use");
1568
1569
  const writeMessage = (message) => {
1570
+ progress?.end();
1569
1571
  if (options.writeStdout !== false)
1570
1572
  deps.writeStdout(message);
1571
1573
  return message;
1572
1574
  };
1573
- const { agentRoot, state } = readOrBootstrapProviderState(command.agent, deps);
1574
- const credential = await readProviderCredentialRecord(command.agent, command.provider, deps);
1575
- if (!credential.ok) {
1576
- if (!command.force) {
1575
+ try {
1576
+ const { agentRoot, state } = readOrBootstrapProviderState(command.agent, deps);
1577
+ progress?.startPhase(`reading ${command.provider} credentials`);
1578
+ const credential = await readProviderCredentialRecord(command.agent, command.provider, deps, {
1579
+ onProgress: (message) => progress?.updateDetail(message),
1580
+ });
1581
+ if (!credential.ok) {
1582
+ progress?.completePhase(`reading ${command.provider} credentials`, credential.reason);
1583
+ if (!command.force) {
1584
+ const message = [
1585
+ `no credentials stored for ${command.provider}.`,
1586
+ `Run \`ouro auth --agent ${command.agent} --provider ${command.provider}\` first.`,
1587
+ ].join("\n");
1588
+ return writeMessage(message);
1589
+ }
1590
+ writeProviderBinding({
1591
+ agentRoot,
1592
+ state,
1593
+ lane: command.lane,
1594
+ provider: command.provider,
1595
+ model: command.model,
1596
+ deps,
1597
+ status: "failed",
1598
+ error: credential.error,
1599
+ });
1600
+ const message = `forced ${command.agent} ${command.lane} to ${command.provider} / ${command.model}: failed (${credential.error})`;
1601
+ return writeMessage(message);
1602
+ }
1603
+ progress?.completePhase(`reading ${command.provider} credentials`, "found");
1604
+ progress?.startPhase(`checking ${command.provider} / ${command.model}`);
1605
+ const pingResult = await (0, provider_ping_1.pingProvider)(command.provider, credentialPingConfig(credential.record), {
1606
+ model: command.model,
1607
+ attemptPolicy: { baseDelayMs: 0 },
1608
+ sleep: deps.sleep,
1609
+ });
1610
+ const attempts = pingAttemptCount(pingResult);
1611
+ const status = pingResult.ok ? "ready" : `failed (${pingResult.message})`;
1612
+ progress?.completePhase(`checking ${command.provider} / ${command.model}`, status);
1613
+ if (!pingResult.ok && !command.force) {
1577
1614
  const message = [
1578
- `no credentials stored for ${command.provider}.`,
1579
- `Run \`ouro auth --agent ${command.agent} --provider ${command.provider}\` first.`,
1615
+ `${command.agent} ${command.lane} ${command.provider} / ${command.model}: failed (${pingResult.message})`,
1616
+ `Fix credentials with \`ouro auth --agent ${command.agent} --provider ${command.provider}\` or force the local binding with \`ouro use --agent ${command.agent} --lane ${command.lane} --provider ${command.provider} --model ${command.model} --force\`.`,
1580
1617
  ].join("\n");
1581
1618
  return writeMessage(message);
1582
1619
  }
@@ -1587,87 +1624,82 @@ async function executeProviderUse(command, deps, options = {}) {
1587
1624
  provider: command.provider,
1588
1625
  model: command.model,
1589
1626
  deps,
1590
- status: "failed",
1591
- error: credential.error,
1627
+ status: pingResult.ok ? "ready" : "failed",
1628
+ credentialRevision: credential.record.revision,
1629
+ ...(!pingResult.ok ? { error: pingResult.message } : {}),
1630
+ ...(attempts !== undefined ? { attempts } : {}),
1631
+ });
1632
+ const message = `${command.force ? "forced " : ""}${command.agent} ${command.lane} ${command.provider} / ${command.model}: ${status}`;
1633
+ (0, runtime_1.emitNervesEvent)({
1634
+ component: "daemon",
1635
+ event: "daemon.provider_use_completed",
1636
+ message: "provider use command completed",
1637
+ meta: { agent: command.agent, lane: command.lane, provider: command.provider, model: command.model, status: pingResult.ok ? "ready" : "failed" },
1592
1638
  });
1593
- const message = `forced ${command.agent} ${command.lane} to ${command.provider} / ${command.model}: failed (${credential.error})`;
1594
1639
  return writeMessage(message);
1595
1640
  }
1596
- const pingResult = await (0, provider_ping_1.pingProvider)(command.provider, credentialPingConfig(credential.record), {
1597
- model: command.model,
1598
- attemptPolicy: { baseDelayMs: 0 },
1599
- sleep: deps.sleep,
1600
- });
1601
- const attempts = pingAttemptCount(pingResult);
1602
- if (!pingResult.ok && !command.force) {
1603
- const message = [
1604
- `${command.agent} ${command.lane} ${command.provider} / ${command.model}: failed (${pingResult.message})`,
1605
- `Fix credentials with \`ouro auth --agent ${command.agent} --provider ${command.provider}\` or force the local binding with \`ouro use --agent ${command.agent} --lane ${command.lane} --provider ${command.provider} --model ${command.model} --force\`.`,
1606
- ].join("\n");
1607
- return writeMessage(message);
1641
+ catch (error) {
1642
+ progress?.end();
1643
+ throw error;
1608
1644
  }
1609
- writeProviderBinding({
1610
- agentRoot,
1611
- state,
1612
- lane: command.lane,
1613
- provider: command.provider,
1614
- model: command.model,
1615
- deps,
1616
- status: pingResult.ok ? "ready" : "failed",
1617
- credentialRevision: credential.record.revision,
1618
- ...(!pingResult.ok ? { error: pingResult.message } : {}),
1619
- ...(attempts !== undefined ? { attempts } : {}),
1620
- });
1621
- const status = pingResult.ok ? "ready" : `failed (${pingResult.message})`;
1622
- const message = `${command.force ? "forced " : ""}${command.agent} ${command.lane} ${command.provider} / ${command.model}: ${status}`;
1623
- (0, runtime_1.emitNervesEvent)({
1624
- component: "daemon",
1625
- event: "daemon.provider_use_completed",
1626
- message: "provider use command completed",
1627
- meta: { agent: command.agent, lane: command.lane, provider: command.provider, model: command.model, status: pingResult.ok ? "ready" : "failed" },
1628
- });
1629
- return writeMessage(message);
1630
1645
  }
1631
1646
  async function executeProviderCheck(command, deps) {
1632
- const { agentRoot, state } = readOrBootstrapProviderState(command.agent, deps);
1633
- const binding = state.lanes[command.lane];
1634
- const credential = await readProviderCredentialRecord(command.agent, binding.provider, deps);
1635
- if (!credential.ok) {
1636
- const message = [
1637
- `${command.agent} ${command.lane} ${binding.provider} / ${binding.model}: unknown (${credential.error})`,
1638
- `Run \`ouro auth --agent ${command.agent} --provider ${binding.provider}\` first.`,
1639
- ].join("\n");
1647
+ const progress = createHumanCommandProgress(deps, "provider check");
1648
+ const writeMessage = (message) => {
1649
+ progress.end();
1640
1650
  deps.writeStdout(message);
1641
1651
  return message;
1652
+ };
1653
+ try {
1654
+ const { agentRoot, state } = readOrBootstrapProviderState(command.agent, deps);
1655
+ const binding = state.lanes[command.lane];
1656
+ progress.startPhase(`reading ${binding.provider} credentials`);
1657
+ const credential = await readProviderCredentialRecord(command.agent, binding.provider, deps, {
1658
+ onProgress: (message) => progress.updateDetail(message),
1659
+ });
1660
+ if (!credential.ok) {
1661
+ progress.completePhase(`reading ${binding.provider} credentials`, credential.reason);
1662
+ const message = [
1663
+ `${command.agent} ${command.lane} ${binding.provider} / ${binding.model}: unknown (${credential.error})`,
1664
+ `Run \`ouro auth --agent ${command.agent} --provider ${binding.provider}\` first.`,
1665
+ ].join("\n");
1666
+ return writeMessage(message);
1667
+ }
1668
+ progress.completePhase(`reading ${binding.provider} credentials`, "found");
1669
+ progress.startPhase(`checking ${binding.provider} / ${binding.model}`);
1670
+ const pingResult = await (0, provider_ping_1.pingProvider)(binding.provider, credentialPingConfig(credential.record), {
1671
+ model: binding.model,
1672
+ attemptPolicy: { baseDelayMs: 0 },
1673
+ sleep: deps.sleep,
1674
+ });
1675
+ const attempts = pingAttemptCount(pingResult);
1676
+ const status = pingResult.ok ? "ready" : `failed (${pingResult.message})`;
1677
+ progress.completePhase(`checking ${binding.provider} / ${binding.model}`, status);
1678
+ writeProviderReadiness({
1679
+ agentRoot,
1680
+ state,
1681
+ lane: command.lane,
1682
+ provider: binding.provider,
1683
+ model: binding.model,
1684
+ deps,
1685
+ status: pingResult.ok ? "ready" : "failed",
1686
+ credentialRevision: credential.record.revision,
1687
+ ...(!pingResult.ok ? { error: pingResult.message } : {}),
1688
+ ...(attempts !== undefined ? { attempts } : {}),
1689
+ });
1690
+ const message = `${command.agent} ${command.lane} ${binding.provider} / ${binding.model}: ${status}`;
1691
+ (0, runtime_1.emitNervesEvent)({
1692
+ component: "daemon",
1693
+ event: "daemon.provider_check_completed",
1694
+ message: "provider check command completed",
1695
+ meta: { agent: command.agent, lane: command.lane, provider: binding.provider, model: binding.model, status: pingResult.ok ? "ready" : "failed" },
1696
+ });
1697
+ return writeMessage(message);
1698
+ }
1699
+ catch (error) {
1700
+ progress.end();
1701
+ throw error;
1642
1702
  }
1643
- const pingResult = await (0, provider_ping_1.pingProvider)(binding.provider, credentialPingConfig(credential.record), {
1644
- model: binding.model,
1645
- attemptPolicy: { baseDelayMs: 0 },
1646
- sleep: deps.sleep,
1647
- });
1648
- const attempts = pingAttemptCount(pingResult);
1649
- writeProviderReadiness({
1650
- agentRoot,
1651
- state,
1652
- lane: command.lane,
1653
- provider: binding.provider,
1654
- model: binding.model,
1655
- deps,
1656
- status: pingResult.ok ? "ready" : "failed",
1657
- credentialRevision: credential.record.revision,
1658
- ...(!pingResult.ok ? { error: pingResult.message } : {}),
1659
- ...(attempts !== undefined ? { attempts } : {}),
1660
- });
1661
- const status = pingResult.ok ? "ready" : `failed (${pingResult.message})`;
1662
- const message = `${command.agent} ${command.lane} ${binding.provider} / ${binding.model}: ${status}`;
1663
- deps.writeStdout(message);
1664
- (0, runtime_1.emitNervesEvent)({
1665
- component: "daemon",
1666
- event: "daemon.provider_check_completed",
1667
- message: "provider check command completed",
1668
- meta: { agent: command.agent, lane: command.lane, provider: binding.provider, model: binding.model, status: pingResult.ok ? "ready" : "failed" },
1669
- });
1670
- return message;
1671
1703
  }
1672
1704
  function renderProviderCredentialLine(credential) {
1673
1705
  if (credential.status === "present") {
@@ -1753,6 +1785,51 @@ async function executeProviderRefresh(command, deps) {
1753
1785
  deps.writeStdout(message);
1754
1786
  return message;
1755
1787
  }
1788
+ async function executeAuthRun(command, deps) {
1789
+ const provider = command.provider ?? (0, auth_flow_1.readAgentConfigForAgent)(command.agent, deps.bundlesRoot).config.humanFacing.provider;
1790
+ /* v8 ignore next -- tests always inject runAuthFlow; default is for production @preserve */
1791
+ const authRunner = deps.runAuthFlow ?? (await Promise.resolve().then(() => __importStar(require("../auth/auth-flow")))).runRuntimeAuthFlow;
1792
+ const progress = createHumanCommandProgress(deps, "auth");
1793
+ progress.startPhase(`authenticating ${provider}`);
1794
+ let result;
1795
+ try {
1796
+ result = await authRunner({
1797
+ agentName: command.agent,
1798
+ provider,
1799
+ promptInput: deps.promptInput,
1800
+ onProgress: (message) => progress.updateDetail(message),
1801
+ });
1802
+ }
1803
+ catch (error) {
1804
+ progress.end();
1805
+ throw error;
1806
+ }
1807
+ progress.completePhase(`authenticating ${provider}`, "credentials stored");
1808
+ // Behavior: ouro auth stores credentials only — does NOT switch provider.
1809
+ // Use `ouro auth switch` to change the active provider.
1810
+ // Verify the credentials actually work by pinging the provider.
1811
+ /* v8 ignore start -- integration: real API ping after auth @preserve */
1812
+ try {
1813
+ progress.startPhase(`verifying ${provider}`);
1814
+ const credential = await readProviderCredentialRecord(command.agent, provider, deps, {
1815
+ onProgress: (message) => progress.updateDetail(message),
1816
+ });
1817
+ const status = credential.ok
1818
+ ? await verifyProviderCredentials(provider, {
1819
+ [provider]: { ...credential.record.config, ...credential.record.credentials },
1820
+ })
1821
+ : `stored but could not be re-read from vault (${credential.error})`;
1822
+ progress.completePhase(`verifying ${provider}`, status);
1823
+ }
1824
+ catch (error) {
1825
+ // Verification failure is non-blocking — credentials were saved regardless.
1826
+ progress.completePhase(`verifying ${provider}`, `skipped (${error instanceof Error ? error.message : String(error)})`);
1827
+ }
1828
+ /* v8 ignore stop */
1829
+ progress.end();
1830
+ deps.writeStdout(result.message);
1831
+ return result.message;
1832
+ }
1756
1833
  async function readinessReportForAgent(agent, deps) {
1757
1834
  const bundlesRoot = deps.bundlesRoot ?? (0, identity_1.getAgentBundlesRoot)();
1758
1835
  try {
@@ -1794,15 +1871,7 @@ async function executeReadinessRepairAction(agent, action, deps) {
1794
1871
  return;
1795
1872
  }
1796
1873
  if (action.kind === "provider-auth") {
1797
- const provider = action.provider;
1798
- const authRunner = deps.runAuthFlow ?? auth_flow_1.runRuntimeAuthFlow;
1799
- const result = await authRunner({
1800
- agentName: agent,
1801
- provider,
1802
- promptInput: deps.promptInput,
1803
- onProgress: deps.writeStdout,
1804
- });
1805
- deps.writeStdout(result.message);
1874
+ await executeAuthRun({ kind: "auth.run", agent, provider: action.provider }, deps);
1806
1875
  await executeProviderRefresh({ kind: "provider.refresh", agent }, deps);
1807
1876
  return;
1808
1877
  }
@@ -3414,83 +3483,68 @@ async function runOuroCli(args, deps = (0, cli_defaults_1.createDefaultOuroCliDe
3414
3483
  }
3415
3484
  // ── auth (local, no daemon socket needed) ──
3416
3485
  if (command.kind === "auth.run") {
3417
- const provider = command.provider ?? (0, auth_flow_1.readAgentConfigForAgent)(command.agent, deps.bundlesRoot).config.humanFacing.provider;
3418
- /* v8 ignore next -- tests always inject runAuthFlow; default is for production @preserve */
3419
- const authRunner = deps.runAuthFlow ?? (await Promise.resolve().then(() => __importStar(require("../auth/auth-flow")))).runRuntimeAuthFlow;
3420
- const progress = createHumanCommandProgress(deps, "auth");
3421
- progress.startPhase(`authenticating ${provider}`);
3422
- let result;
3423
- try {
3424
- result = await authRunner({
3425
- agentName: command.agent,
3426
- provider,
3427
- promptInput: deps.promptInput,
3428
- onProgress: (message) => progress.updateDetail(message),
3429
- });
3430
- }
3431
- catch (error) {
3432
- progress.end();
3433
- throw error;
3434
- }
3435
- progress.completePhase(`authenticating ${provider}`, "credentials stored");
3436
- // Behavior: ouro auth stores credentials only — does NOT switch provider.
3437
- // Use `ouro auth switch` to change the active provider.
3438
- // Verify the credentials actually work by pinging the provider
3439
- /* v8 ignore start -- integration: real API ping after auth @preserve */
3440
- try {
3441
- progress.startPhase(`verifying ${provider}`);
3442
- const credential = await readProviderCredentialRecord(command.agent, provider, deps);
3443
- const status = credential.ok
3444
- ? await verifyProviderCredentials(provider, {
3445
- [provider]: { ...credential.record.config, ...credential.record.credentials },
3446
- })
3447
- : `stored but could not be re-read from vault (${credential.error})`;
3448
- progress.completePhase(`verifying ${provider}`, status);
3449
- }
3450
- catch (error) {
3451
- // Verification failure is non-blocking — credentials were saved regardless.
3452
- progress.completePhase(`verifying ${provider}`, `skipped (${error instanceof Error ? error.message : String(error)})`);
3453
- }
3454
- /* v8 ignore stop */
3455
- progress.end();
3456
- deps.writeStdout(result.message);
3457
- return result.message;
3486
+ return executeAuthRun(command, deps);
3458
3487
  }
3459
3488
  // ── auth verify (local, no daemon socket needed) ──
3460
3489
  /* v8 ignore start -- auth verify/switch: tested in daemon-cli.test.ts but v8 traces differ in CI @preserve */
3461
3490
  if (command.kind === "auth.verify") {
3462
- const poolResult = await (0, provider_credentials_1.refreshProviderCredentialPool)(command.agent);
3463
- if (!poolResult.ok) {
3464
- const message = `vault unavailable: ${poolResult.error}\n${(0, vault_unlock_1.vaultUnlockReplaceRecoverFix)(command.agent, "Then retry 'ouro auth verify'.")}`;
3491
+ const progress = createHumanCommandProgress(deps, "auth verify");
3492
+ const writeMessage = (message) => {
3493
+ progress.end();
3465
3494
  deps.writeStdout(message);
3466
3495
  return message;
3467
- }
3468
- if (command.provider) {
3469
- const record = poolResult.pool.providers[command.provider];
3470
- if (!record) {
3471
- const message = `${command.provider}: missing. Run \`ouro auth --agent ${command.agent} --provider ${command.provider}\`.`;
3472
- deps.writeStdout(message);
3473
- return message;
3474
- }
3475
- const status = await verifyProviderCredentials(command.provider, {
3476
- [command.provider]: { ...record.config, ...record.credentials },
3496
+ };
3497
+ try {
3498
+ progress.startPhase("reading provider credentials");
3499
+ const poolResult = await (0, provider_credentials_1.refreshProviderCredentialPool)(command.agent, {
3500
+ onProgress: (message) => progress.updateDetail(message),
3477
3501
  });
3478
- const message = `${command.provider}: ${status}`;
3479
- deps.writeStdout(message);
3480
- return message;
3502
+ if (!poolResult.ok) {
3503
+ progress.completePhase("reading provider credentials", poolResult.reason);
3504
+ const message = `vault unavailable: ${poolResult.error}\n${(0, vault_unlock_1.vaultUnlockReplaceRecoverFix)(command.agent, "Then retry 'ouro auth verify'.")}`;
3505
+ return writeMessage(message);
3506
+ }
3507
+ const providerCount = Object.keys(poolResult.pool.providers).length;
3508
+ progress.completePhase("reading provider credentials", `${providerCount} provider${providerCount === 1 ? "" : "s"}`);
3509
+ if (command.provider) {
3510
+ const record = poolResult.pool.providers[command.provider];
3511
+ if (!record) {
3512
+ const message = `${command.provider}: missing. Run \`ouro auth --agent ${command.agent} --provider ${command.provider}\`.`;
3513
+ return writeMessage(message);
3514
+ }
3515
+ progress.startPhase(`verifying ${command.provider}`);
3516
+ const status = await verifyProviderCredentials(command.provider, {
3517
+ [command.provider]: { ...record.config, ...record.credentials },
3518
+ });
3519
+ progress.completePhase(`verifying ${command.provider}`, status);
3520
+ const message = `${command.provider}: ${status}`;
3521
+ return writeMessage(message);
3522
+ }
3523
+ const lines = [];
3524
+ const entries = Object.entries(poolResult.pool.providers);
3525
+ if (entries.length > 0) {
3526
+ progress.startPhase("verifying providers");
3527
+ }
3528
+ for (const [p, record] of entries) {
3529
+ const status = await verifyProviderCredentials(p, {
3530
+ [p]: { ...record.config, ...record.credentials },
3531
+ });
3532
+ const line = `${p}: ${status}`;
3533
+ lines.push(line);
3534
+ progress.updateDetail(line);
3535
+ }
3536
+ if (entries.length > 0) {
3537
+ progress.completePhase("verifying providers", `${entries.length} checked`);
3538
+ }
3539
+ if (lines.length === 0)
3540
+ lines.push(`no provider credentials in ${command.agent}'s vault`);
3541
+ const message = lines.join("\n");
3542
+ return writeMessage(message);
3481
3543
  }
3482
- const lines = [];
3483
- for (const [p, record] of Object.entries(poolResult.pool.providers)) {
3484
- const status = await verifyProviderCredentials(p, {
3485
- [p]: { ...record.config, ...record.credentials },
3486
- });
3487
- lines.push(`${p}: ${status}`);
3544
+ catch (error) {
3545
+ progress.end();
3546
+ throw error;
3488
3547
  }
3489
- if (lines.length === 0)
3490
- lines.push(`no provider credentials in ${command.agent}'s vault`);
3491
- const message = lines.join("\n");
3492
- deps.writeStdout(message);
3493
- return message;
3494
3548
  }
3495
3549
  // ── auth switch (local, no daemon socket needed) ──
3496
3550
  if (command.kind === "auth.switch") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ouro.bot/cli",
3
- "version": "0.1.0-alpha.419",
3
+ "version": "0.1.0-alpha.420",
4
4
  "main": "dist/heart/daemon/ouro-entry.js",
5
5
  "bin": {
6
6
  "cli": "dist/heart/daemon/ouro-bot-entry.js",