@workbench-ai/workbench 0.0.96 → 0.0.98
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/index.js +42 -22
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -1850,6 +1850,9 @@ async function requestDeviceAuthorization(baseUrl) {
|
|
|
1850
1850
|
});
|
|
1851
1851
|
}
|
|
1852
1852
|
if (!response.ok) {
|
|
1853
|
+
if (isRetryableHttpStatus(response.status)) {
|
|
1854
|
+
throw deviceLoginUnavailableError("start", response.status, response.statusText, text);
|
|
1855
|
+
}
|
|
1853
1856
|
const excerpt = readResponseError(text);
|
|
1854
1857
|
throw new WorkbenchCodedError("login_denied", `Device login failed: ${response.status}${excerpt ? ` ${excerpt}` : response.statusText ? ` ${response.statusText}` : ""}`, {
|
|
1855
1858
|
exitCode: 1,
|
|
@@ -1889,6 +1892,9 @@ async function pollDeviceToken(baseUrl, authorization, timeoutSeconds) {
|
|
|
1889
1892
|
if (response.ok) {
|
|
1890
1893
|
return JSON.parse(text);
|
|
1891
1894
|
}
|
|
1895
|
+
if (isRetryableHttpStatus(response.status)) {
|
|
1896
|
+
throw deviceLoginUnavailableError("wait", response.status, response.statusText, text);
|
|
1897
|
+
}
|
|
1892
1898
|
const error = readResponseError(text) ?? "authorization_pending";
|
|
1893
1899
|
if (error === "slow_down") {
|
|
1894
1900
|
intervalMs += 5000;
|
|
@@ -1913,6 +1919,18 @@ async function pollDeviceToken(baseUrl, authorization, timeoutSeconds) {
|
|
|
1913
1919
|
exitCode: 1,
|
|
1914
1920
|
});
|
|
1915
1921
|
}
|
|
1922
|
+
function deviceLoginUnavailableError(phase, status, statusText, text) {
|
|
1923
|
+
const excerpt = readResponseError(text);
|
|
1924
|
+
const detail = `${status}${excerpt ? ` ${excerpt}` : statusText ? ` ${statusText}` : ""}`;
|
|
1925
|
+
const command = phase === "start"
|
|
1926
|
+
? "workbench login --start-only --no-open"
|
|
1927
|
+
: `workbench login --wait --timeout ${LOGIN_WAIT_TIMEOUT_SECONDS}`;
|
|
1928
|
+
return new WorkbenchCodedError("service_unavailable", `Workbench Cloud login is temporarily unavailable: ${detail}`, {
|
|
1929
|
+
retryable: true,
|
|
1930
|
+
remediation: `Retry ${command}.`,
|
|
1931
|
+
exitCode: 1,
|
|
1932
|
+
});
|
|
1933
|
+
}
|
|
1916
1934
|
async function fetchWorkbenchUsername(baseUrl, accessToken) {
|
|
1917
1935
|
const response = await fetch(`${baseUrl}/api/workbench/profile`, {
|
|
1918
1936
|
headers: { authorization: `Bearer ${accessToken}` },
|
|
@@ -2150,7 +2168,10 @@ function isTransientFetchError(error) {
|
|
|
2150
2168
|
return /(?:fetch failed|socket hang up|ECONNRESET|EPIPE|UND_ERR_SOCKET|terminated)/iu.test(errorMessage(error));
|
|
2151
2169
|
}
|
|
2152
2170
|
function isTransientApiRequestError(error) {
|
|
2153
|
-
return error instanceof WorkbenchApiRequestError && (error.status
|
|
2171
|
+
return error instanceof WorkbenchApiRequestError && isRetryableHttpStatus(error.status);
|
|
2172
|
+
}
|
|
2173
|
+
function isRetryableHttpStatus(status) {
|
|
2174
|
+
return status === 429 || status >= 500;
|
|
2154
2175
|
}
|
|
2155
2176
|
function isIdempotentApiRequestMethod(method) {
|
|
2156
2177
|
return method === "GET" || method === "PUT" || method === "DELETE";
|
|
@@ -2246,21 +2267,10 @@ async function collectAdapterAuthBundle(args) {
|
|
|
2246
2267
|
});
|
|
2247
2268
|
}
|
|
2248
2269
|
if (args.method === "oauth") {
|
|
2249
|
-
const profile = await requiredAuthFile(args.profileRoot, ".claude.json", {
|
|
2250
|
-
provider: "Claude auth",
|
|
2251
|
-
remediation: "claude setup-token && workbench login claude --method oauth",
|
|
2252
|
-
});
|
|
2253
|
-
const portableToken = await requiredAnyAuthFile(args.profileRoot, [
|
|
2254
|
-
".claude/oauth-token",
|
|
2255
|
-
".claude/.credentials.json",
|
|
2256
|
-
], {
|
|
2257
|
-
provider: "Claude portable OAuth token",
|
|
2258
|
-
remediation: "claude setup-token && workbench login claude --method oauth",
|
|
2259
|
-
});
|
|
2260
2270
|
return createWorkbenchAdapterAuthBundle({
|
|
2261
2271
|
target: args.target,
|
|
2262
2272
|
method: args.method,
|
|
2263
|
-
files:
|
|
2273
|
+
files: await collectClaudeOAuthFiles(args.profileRoot),
|
|
2264
2274
|
});
|
|
2265
2275
|
}
|
|
2266
2276
|
if (args.method === "bedrock") {
|
|
@@ -2309,15 +2319,25 @@ async function requiredAuthFile(root, relativePath, guidance) {
|
|
|
2309
2319
|
}
|
|
2310
2320
|
return file;
|
|
2311
2321
|
}
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2322
|
+
const CLAUDE_OAUTH_PROFILE_PATH = ".claude.json";
|
|
2323
|
+
const CLAUDE_OAUTH_TOKEN_PATHS = [".claude/oauth-token", ".claude/.credentials.json"];
|
|
2324
|
+
const CLAUDE_OAUTH_REMEDIATION = "claude setup-token && workbench login claude --method oauth";
|
|
2325
|
+
async function collectClaudeOAuthFiles(root) {
|
|
2326
|
+
const [profile] = await optionalAuthFiles(root, [CLAUDE_OAUTH_PROFILE_PATH]);
|
|
2327
|
+
const [portableToken] = await optionalAuthFiles(root, CLAUDE_OAUTH_TOKEN_PATHS);
|
|
2328
|
+
if (profile && portableToken) {
|
|
2329
|
+
return [profile, portableToken];
|
|
2330
|
+
}
|
|
2331
|
+
const missingRelativePaths = [
|
|
2332
|
+
...(!profile ? [CLAUDE_OAUTH_PROFILE_PATH] : []),
|
|
2333
|
+
...(!portableToken ? [...CLAUDE_OAUTH_TOKEN_PATHS] : []),
|
|
2334
|
+
];
|
|
2335
|
+
throw new WorkbenchCodedError("provider_oauth_missing", "Claude OAuth capture requires Claude Code's profile and portable OAuth token.", {
|
|
2336
|
+
remediation: CLAUDE_OAUTH_REMEDIATION,
|
|
2337
|
+
subject: {
|
|
2338
|
+
paths: missingRelativePaths.map((entry) => path.join(root, entry)),
|
|
2339
|
+
relativePaths: missingRelativePaths,
|
|
2340
|
+
},
|
|
2321
2341
|
exitCode: 2,
|
|
2322
2342
|
});
|
|
2323
2343
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@workbench-ai/workbench",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.98",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/workbench-ai/workbench.git",
|
|
@@ -21,10 +21,10 @@
|
|
|
21
21
|
],
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"yaml": "^2.8.2",
|
|
24
|
-
"@workbench-ai/workbench-built-in-adapters": "0.0.
|
|
25
|
-
"@workbench-ai/workbench-protocol": "0.0.
|
|
26
|
-
"@workbench-ai/workbench-core": "0.0.
|
|
27
|
-
"@workbench-ai/workbench-contract": "0.0.
|
|
24
|
+
"@workbench-ai/workbench-built-in-adapters": "0.0.98",
|
|
25
|
+
"@workbench-ai/workbench-protocol": "0.0.98",
|
|
26
|
+
"@workbench-ai/workbench-core": "0.0.98",
|
|
27
|
+
"@workbench-ai/workbench-contract": "0.0.98"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@tailwindcss/postcss": "^4.2.2",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"react-dom": "^19.2.0",
|
|
36
36
|
"typescript": "^5.9.2",
|
|
37
37
|
"vitest": "^3.2.4",
|
|
38
|
-
"@workbench-ai/workbench-ui": "0.0.
|
|
38
|
+
"@workbench-ai/workbench-ui": "0.0.98"
|
|
39
39
|
},
|
|
40
40
|
"scripts": {
|
|
41
41
|
"build": "rm -rf dist && tsc -p tsconfig.json && chmod 755 dist/workbench.js && node ./scripts/build-dev-open-assets.mjs",
|