@bivy/bivy 0.18.4-staging.5 → 0.18.4-staging.6

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.
@@ -2137,20 +2137,6 @@ a.queue-item:hover { border-color: var(--line-strong); background: var(--surface
2137
2137
  .run-sheet-recovery { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
2138
2138
  .run-sheet-recovery .btn.sm { padding: var(--space-1) var(--space-3); }
2139
2139
 
2140
- .composer-starter {
2141
- display: flex; align-items: center; justify-content: space-between; gap: var(--space-3);
2142
- margin: 0 var(--space-3) var(--space-2); padding: var(--space-3); border: 1px solid var(--line);
2143
- border-radius: var(--radius-md); background: var(--surface);
2144
- }
2145
- .composer-starter > div { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; }
2146
- .composer-starter strong { font-size: var(--text-sm); color: var(--ink); }
2147
- .composer-starter span { font-size: var(--text-xs); line-height: var(--lh-sm); color: var(--muted); }
2148
- .composer-starter .btn { flex: none; max-width: 100%; white-space: normal; overflow-wrap: anywhere; }
2149
- @media (max-width: 520px) {
2150
- .composer-starter { align-items: stretch; flex-direction: column; }
2151
- .composer-starter .btn { min-height: var(--space-7); }
2152
- }
2153
-
2154
2140
  /* Review surface (C3): state badges, checks strip, view-mode toggle, file tree,
2155
2141
  per-file actions, and the split (side-by-side) diff layout. */
2156
2142
  .changes-meta { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; padding: 6px 10px; border-bottom: 1px solid var(--line); }
@@ -3167,9 +3153,8 @@ p.setup-note .btn.link { min-height: 44px; margin-block: calc((1lh - 44px) / 2);
3167
3153
  letter-spacing: -0.01em;
3168
3154
  }
3169
3155
 
3170
- /* Activation readiness strip (src/components/ReadinessChecklist.tsx) — the honest
3171
- "get to your first agent response" checklist shown until the agent answers. */
3172
- .readiness { margin: 10px 12px 0; }
3156
+ /* Setup checks and the ready-to-message confirmation. */
3157
+ .readiness { margin: var(--space-3) var(--space-3) 0; }
3173
3158
  .readiness-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
3174
3159
  .readiness-title { font-weight: 600; font-size: var(--text-base); letter-spacing: -0.01em; }
3175
3160
  .readiness-dismiss {
@@ -3179,8 +3164,7 @@ p.setup-note .btn.link { min-height: 44px; margin-block: calc((1lh - 44px) / 2);
3179
3164
  .readiness-dismiss:hover { background: var(--surface-2); color: var(--ink); }
3180
3165
  .readiness-passed { margin: 0 0 var(--space-2); color: var(--ok); font-size: var(--text-sm); font-weight: var(--weight-medium); }
3181
3166
  .readiness-checks { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
3182
- /* Completed setup is summarized above. Keeping six verbose rows after five are
3183
- already done buried the only useful state (waiting for the first answer). */
3167
+ /* Summarize completed checks so the next setup action stays visible. */
3184
3168
  .readiness-check.state-passed { display: none; }
3185
3169
  .readiness-check { display: flex; align-items: baseline; gap: 8px; font-size: var(--text-sm); }
3186
3170
  .readiness-mark {
@@ -0,0 +1,15 @@
1
+ /** Use the same configured providers as the model picker, including environment
2
+ * credentials. An unrelated rejected key must not hide a usable provider. */
3
+ export async function credentialReadiness(providers, probe) {
4
+ const configured = providers.filter((provider) => provider.configured);
5
+ const results = await Promise.all(configured.map((provider) => probe(provider.id)));
6
+ const usable = results.find((result) => result.ok);
7
+ const result = usable ?? results[0];
8
+ return {
9
+ configured: configured.length > 0,
10
+ providers: configured.map((provider) => provider.id),
11
+ probed: result?.probed ?? false,
12
+ ok: Boolean(usable),
13
+ ...(result?.reason ? { reason: result.reason } : {}),
14
+ };
15
+ }
@@ -85,7 +85,7 @@ export function isAnthropicAuthError(raw) {
85
85
  export async function probeAnthropicAccess(apiKey, deps = {}) {
86
86
  const key = apiKey?.trim();
87
87
  // Subscription/OAuth tokens are not API keys; there is no safe read probe.
88
- if (!key || !key.startsWith("sk-"))
88
+ if (!key || !key.startsWith("sk-") || key.startsWith("sk-ant-oat"))
89
89
  return { probed: false, ok: true, reason: "no API key to probe" };
90
90
  const doFetch = deps.fetch ?? fetch;
91
91
  const base = (deps.baseUrl ?? "https://api.anthropic.com").replace(/\/+$/, "");
package/dist/server.js CHANGED
@@ -50,6 +50,7 @@ import { passWebhookFilter } from "./automation-filter-gate.js";
50
50
  import { isModelAuthError, authProviderForSession, classifyModelAuthError } from "./runtime/auth-errors.js";
51
51
  import { createCredentialVault, migrateVaultDir } from "./runtime/credential-store.js";
52
52
  import { probeAnthropicAccess } from "./runtime/anthropic-preflight.js";
53
+ import { credentialReadiness } from "./runtime/activation-readiness.js";
53
54
  import { createSessionNamer, fallbackSessionName } from "./session/session-namer.js";
54
55
  import { createBranchPublish } from "./session/branch-publish.js";
55
56
  import { createForkStandUp } from "./session/fork-standup.js";
@@ -10997,32 +10998,28 @@ app.get("/api/repos", async (_req, res) => {
10997
10998
  // live. Inconclusive provider/network failures remain "unknown" instead of
10998
10999
  // falsely blocking activation.
10999
11000
  async function activationReadinessSnapshot() {
11000
- const vault = createCredentialVault(credsDir, piDir);
11001
- const configured = await vault.list();
11002
- const anthropic = configured.some((entry) => entry.providerId === "anthropic")
11003
- ? await vault.read("anthropic")
11004
- : undefined;
11005
- const anthropicProbe = anthropic?.type === "api_key"
11006
- ? await probeAnthropicAccess(typeof anthropic.key === "string" ? anthropic.key : undefined)
11007
- : undefined;
11008
- const repos = await listAccessibleRepos();
11009
- const repositoryChosen = Boolean(await gitRepoRoot(defaultWorkspace));
11001
+ const [credential, repositoryChosen, workspaceReady] = await Promise.all([
11002
+ listProviders(credsDir, piDir).then((providers) => credentialReadiness(providers, async (provider) => {
11003
+ if (provider !== "anthropic")
11004
+ return { probed: false, ok: true };
11005
+ const credential = await createCredentialVault(credsDir, piDir).read(provider);
11006
+ if (credential?.type === "oauth")
11007
+ return { probed: false, ok: true };
11008
+ return probeAnthropicAccess(credential?.type === "api_key" && typeof credential.key === "string"
11009
+ ? credential.key : process.env.ANTHROPIC_API_KEY);
11010
+ })),
11011
+ gitRepoRoot(defaultWorkspace).then(Boolean),
11012
+ fs.promises.access(defaultWorkspace, fs.constants.R_OK | fs.constants.W_OK).then(() => true, () => false),
11013
+ ]);
11010
11014
  return {
11011
- credential: {
11012
- configured: configured.length > 0,
11013
- providers: configured.map((entry) => entry.providerId),
11014
- probed: Boolean(anthropicProbe?.probed),
11015
- ok: configured.length > 0 && anthropicProbe?.ok !== false,
11016
- ...(anthropicProbe?.reason ? { reason: anthropicProbe.reason } : {}),
11017
- },
11015
+ credential,
11018
11016
  repository: {
11019
11017
  chosen: repositoryChosen,
11020
11018
  probed: true,
11021
- // GitHub login proves that repositories can be listed, not that a target
11022
- // repository has been selected or cloned for the first task.
11023
- ok: repositoryChosen,
11024
- authed: repos.authed,
11025
- ...(repos.error ? { reason: repos.error } : {}),
11019
+ // A first message can run in the default workspace without a Git repo.
11020
+ // Listing remote repositories is unrelated and can take tens of seconds.
11021
+ ok: workspaceReady,
11022
+ authed: false,
11026
11023
  },
11027
11024
  };
11028
11025
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bivy/bivy",
3
- "version": "0.18.4-staging.5",
3
+ "version": "0.18.4-staging.6",
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.",