@bivy/bivy 0.18.4-staging.5 → 0.18.4-staging.7
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/dist/apps/styles.css
CHANGED
|
@@ -1097,24 +1097,25 @@ button.sheet-action:last-child { border-bottom: 0; }
|
|
|
1097
1097
|
}
|
|
1098
1098
|
.image-viewer-img { min-width: 0; min-height: 0; max-width: 100%; max-height: 100%; object-fit: contain; border-radius: var(--radius-sm); cursor: default; }
|
|
1099
1099
|
.image-viewer-close {
|
|
1100
|
-
position: absolute; top: max(
|
|
1101
|
-
border: 0; background: var(--overlay); color: var(--accent-contrast); width: 40px; height: 40px;
|
|
1102
|
-
border-radius: var(--radius-full); font-size: 26px; line-height: 1; cursor: pointer;
|
|
1100
|
+
position: absolute; top: max(var(--space-3), env(safe-area-inset-top)); right: max(var(--space-4), env(safe-area-inset-right));
|
|
1103
1101
|
}
|
|
1102
|
+
.image-viewer-close, .image-viewer-nav {
|
|
1103
|
+
border: 1px solid var(--line-strong); background: var(--surface-3); color: var(--ink);
|
|
1104
|
+
width: var(--space-7); height: var(--space-7); border-radius: var(--radius-full);
|
|
1105
|
+
font-size: var(--text-3xl); line-height: 1; cursor: pointer;
|
|
1106
|
+
display: grid; place-items: center;
|
|
1107
|
+
}
|
|
1108
|
+
.image-viewer-close:hover, .image-viewer-nav:hover { background: var(--surface-2); }
|
|
1104
1109
|
/* Prev/next page controls in the multi-image gallery — mirror the close button. */
|
|
1105
1110
|
.image-viewer-nav {
|
|
1106
1111
|
position: absolute; top: 50%; transform: translateY(-50%);
|
|
1107
|
-
border: 0; background: var(--overlay); color: var(--accent-contrast);
|
|
1108
|
-
width: 44px; height: 44px; border-radius: var(--radius-full);
|
|
1109
|
-
font-size: 30px; line-height: 1; cursor: pointer;
|
|
1110
|
-
display: grid; place-items: center;
|
|
1111
1112
|
}
|
|
1112
1113
|
.image-viewer-nav.prev { left: max(var(--space-3), env(safe-area-inset-left)); }
|
|
1113
1114
|
.image-viewer-nav.next { right: max(var(--space-4), env(safe-area-inset-right)); }
|
|
1114
1115
|
.image-viewer-count {
|
|
1115
1116
|
position: absolute; bottom: max(var(--space-4), env(safe-area-inset-bottom));
|
|
1116
1117
|
left: 50%; transform: translateX(-50%); cursor: default;
|
|
1117
|
-
background: var(--
|
|
1118
|
+
background: var(--surface-3); color: var(--ink);
|
|
1118
1119
|
padding: var(--space-1) var(--space-3); border-radius: var(--radius-full);
|
|
1119
1120
|
font-size: var(--text-sm); font-variant-numeric: tabular-nums;
|
|
1120
1121
|
}
|
|
@@ -2137,20 +2138,6 @@ a.queue-item:hover { border-color: var(--line-strong); background: var(--surface
|
|
|
2137
2138
|
.run-sheet-recovery { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
|
|
2138
2139
|
.run-sheet-recovery .btn.sm { padding: var(--space-1) var(--space-3); }
|
|
2139
2140
|
|
|
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
2141
|
/* Review surface (C3): state badges, checks strip, view-mode toggle, file tree,
|
|
2155
2142
|
per-file actions, and the split (side-by-side) diff layout. */
|
|
2156
2143
|
.changes-meta { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; padding: 6px 10px; border-bottom: 1px solid var(--line); }
|
|
@@ -3167,9 +3154,8 @@ p.setup-note .btn.link { min-height: 44px; margin-block: calc((1lh - 44px) / 2);
|
|
|
3167
3154
|
letter-spacing: -0.01em;
|
|
3168
3155
|
}
|
|
3169
3156
|
|
|
3170
|
-
/*
|
|
3171
|
-
|
|
3172
|
-
.readiness { margin: 10px 12px 0; }
|
|
3157
|
+
/* Setup checks and the ready-to-message confirmation. */
|
|
3158
|
+
.readiness { margin: var(--space-3) var(--space-3) 0; }
|
|
3173
3159
|
.readiness-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
|
|
3174
3160
|
.readiness-title { font-weight: 600; font-size: var(--text-base); letter-spacing: -0.01em; }
|
|
3175
3161
|
.readiness-dismiss {
|
|
@@ -3179,8 +3165,7 @@ p.setup-note .btn.link { min-height: 44px; margin-block: calc((1lh - 44px) / 2);
|
|
|
3179
3165
|
.readiness-dismiss:hover { background: var(--surface-2); color: var(--ink); }
|
|
3180
3166
|
.readiness-passed { margin: 0 0 var(--space-2); color: var(--ok); font-size: var(--text-sm); font-weight: var(--weight-medium); }
|
|
3181
3167
|
.readiness-checks { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
|
|
3182
|
-
/*
|
|
3183
|
-
already done buried the only useful state (waiting for the first answer). */
|
|
3168
|
+
/* Summarize completed checks so the next setup action stays visible. */
|
|
3184
3169
|
.readiness-check.state-passed { display: none; }
|
|
3185
3170
|
.readiness-check { display: flex; align-items: baseline; gap: 8px; font-size: var(--text-sm); }
|
|
3186
3171
|
.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
|
|
11001
|
-
|
|
11002
|
-
|
|
11003
|
-
|
|
11004
|
-
|
|
11005
|
-
|
|
11006
|
-
|
|
11007
|
-
|
|
11008
|
-
|
|
11009
|
-
|
|
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
|
-
//
|
|
11022
|
-
//
|
|
11023
|
-
ok:
|
|
11024
|
-
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