@bivy/bivy 0.18.7-staging.1 → 0.18.7-staging.3

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.
@@ -78,14 +78,29 @@ export class NodeCredentialResolver {
78
78
  // under the store lock).
79
79
  let token = typeof cred.access === "string" ? cred.access : "";
80
80
  const expires = Number(cred.expires) || 0;
81
- if (!token || expires <= Date.now() + OAUTH_REFRESH_SKEW_MS || context?.rejectedToken === token) {
81
+ // Spent: the provider already refused this exact token, or its lifetime is
82
+ // over. A token merely inside the refresh skew is still live — that case
83
+ // refreshes early but may keep the current token if the refresh fails.
84
+ // An unknown expiry (0) is never assumed spent.
85
+ const spent = !token || context?.rejectedToken === token || (expires > 0 && expires <= Date.now());
86
+ if (spent || expires <= Date.now() + OAUTH_REFRESH_SKEW_MS) {
82
87
  // Refresh the SELECTED record (its label), not just the provider default —
83
88
  // so a second account on the same provider is left untouched. A provider
84
89
  // 401 forces refresh even before expiry; the rejected-token guard is
85
90
  // re-checked under the OAuth store lock to avoid duplicate rotations.
86
91
  const refreshed = await this.oauth.refresh(id, selection.record.label, context?.rejectedToken).catch(() => undefined);
87
- if (refreshed)
92
+ if (refreshed && refreshed !== token)
88
93
  token = refreshed;
94
+ // The refresh failed (commonly: the provider's own CLI rotated the refresh
95
+ // token out from under this copy) and what we hold is spent. Report NO
96
+ // credential rather than handing the agent a token that cannot work:
97
+ // Bivy's env var outranks the agent's own login, so returning it shadows a
98
+ // perfectly good `claude`/`codex` CLI session on this machine with a dead
99
+ // one — the "it ignored my local credentials" failure. With none, the
100
+ // agent falls back to that login, and an agent with no login of its own
101
+ // gets the vault's actionable "no credential" message instead of a 401.
102
+ else if (spent)
103
+ return undefined;
89
104
  }
90
105
  if (!token)
91
106
  return undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bivy/bivy",
3
- "version": "0.18.7-staging.1",
3
+ "version": "0.18.7-staging.3",
4
4
  "type": "module",
5
5
  "license": "AGPL-3.0-only",
6
6
  "description": "Run coding agents on machines you own. Open-source, self-hostable agent workspace.",