@guildai/cli 0.11.0 → 0.12.0
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/auth-CRMO5O3N.js +29 -0
- package/dist/auth-CRMO5O3N.js.map +7 -0
- package/dist/chat-5VX2WJH2.js +303 -0
- package/dist/chat-5VX2WJH2.js.map +7 -0
- package/dist/chat-SIKDYZQK.js +31 -0
- package/dist/chat-SIKDYZQK.js.map +7 -0
- package/dist/chunk-56YCMGL3.js +522 -0
- package/dist/chunk-56YCMGL3.js.map +7 -0
- package/dist/chunk-6EX6E7WP.js +7042 -0
- package/dist/chunk-6EX6E7WP.js.map +7 -0
- package/dist/chunk-B7VAF5UG.js +532 -0
- package/dist/chunk-B7VAF5UG.js.map +7 -0
- package/dist/chunk-DOIYVBNY.js +3057 -0
- package/dist/chunk-DOIYVBNY.js.map +7 -0
- package/dist/chunk-ENKEEJ45.js +17 -0
- package/dist/chunk-ENKEEJ45.js.map +7 -0
- package/dist/chunk-IBRKVGMZ.js +97041 -0
- package/dist/chunk-IBRKVGMZ.js.map +7 -0
- package/dist/chunk-LFMQJOKC.js +19778 -0
- package/dist/chunk-LFMQJOKC.js.map +7 -0
- package/dist/chunk-M347HP6M.js +22896 -0
- package/dist/chunk-M347HP6M.js.map +7 -0
- package/dist/chunk-OYQ476FQ.js +44 -0
- package/dist/chunk-OYQ476FQ.js.map +7 -0
- package/dist/chunk-PNCUR4OB.js +257 -0
- package/dist/chunk-PNCUR4OB.js.map +7 -0
- package/dist/chunk-RIG2HZWM.js +317 -0
- package/dist/chunk-RIG2HZWM.js.map +7 -0
- package/dist/chunk-SPZPZXUN.js +826 -0
- package/dist/chunk-SPZPZXUN.js.map +7 -0
- package/dist/chunk-VVSOU6ON.js +53 -0
- package/dist/chunk-VVSOU6ON.js.map +7 -0
- package/dist/chunk-X3ADGWOF.js +3643 -0
- package/dist/chunk-X3ADGWOF.js.map +7 -0
- package/dist/commands/skill/create.d.ts +3 -0
- package/dist/commands/skill/get.d.ts +3 -0
- package/dist/commands/skill/list.d.ts +3 -0
- package/dist/commands/skill/update.d.ts +3 -0
- package/dist/commands/skill/version/create.d.ts +3 -0
- package/dist/commands/skill/version/get.d.ts +3 -0
- package/dist/commands/skill/version/list.d.ts +3 -0
- package/dist/devtools-AO7YSDOD.js +67 -0
- package/dist/devtools-AO7YSDOD.js.map +7 -0
- package/dist/dist-4CBK6X5H.js +1566 -0
- package/dist/dist-4CBK6X5H.js.map +7 -0
- package/dist/esm-FRAVZP4J.js +13 -0
- package/dist/esm-FRAVZP4J.js.map +7 -0
- package/dist/execa-XQMWSABC.js +35 -0
- package/dist/execa-XQMWSABC.js.map +7 -0
- package/dist/index.js +8230 -263
- package/dist/index.js.map +7 -0
- package/dist/lib/api-types.d.ts +44 -0
- package/dist/lib/config.d.ts +9 -0
- package/dist/lib/errors.d.ts +1 -1
- package/dist/lib/output.d.ts +11 -1
- package/dist/lib/session-events.d.ts +1 -1
- package/dist/lib/session-polling.d.ts +24 -1
- package/dist/lib/websocket-client.d.ts +46 -0
- package/dist/open-RF4X5MOP.js +13 -0
- package/dist/open-RF4X5MOP.js.map +7 -0
- package/dist/server-JYVH64FD.js +27659 -0
- package/dist/server-JYVH64FD.js.map +7 -0
- package/dist/test-SNIYRJ32.js +692 -0
- package/dist/test-SNIYRJ32.js.map +7 -0
- package/docs/skills/codex-agent-dev.md +2 -2
- package/package.json +8 -12
- package/dist/commands/agent/chat.js +0 -281
- package/dist/commands/agent/clone.js +0 -118
- package/dist/commands/agent/code.js +0 -87
- package/dist/commands/agent/fork.js +0 -220
- package/dist/commands/agent/get.js +0 -37
- package/dist/commands/agent/grep.js +0 -107
- package/dist/commands/agent/init.js +0 -403
- package/dist/commands/agent/list.js +0 -110
- package/dist/commands/agent/logs.js +0 -62
- package/dist/commands/agent/owners.js +0 -74
- package/dist/commands/agent/publish.js +0 -91
- package/dist/commands/agent/pull.js +0 -194
- package/dist/commands/agent/revalidate.js +0 -56
- package/dist/commands/agent/save.js +0 -345
- package/dist/commands/agent/search.js +0 -61
- package/dist/commands/agent/tags/add.js +0 -73
- package/dist/commands/agent/tags/list.js +0 -43
- package/dist/commands/agent/tags/remove.js +0 -84
- package/dist/commands/agent/tags/set.js +0 -71
- package/dist/commands/agent/test.js +0 -489
- package/dist/commands/agent/unpublish.js +0 -64
- package/dist/commands/agent/update.js +0 -118
- package/dist/commands/agent/versions.js +0 -55
- package/dist/commands/agent/workspaces.js +0 -54
- package/dist/commands/auth/login.js +0 -31
- package/dist/commands/auth/logout.js +0 -24
- package/dist/commands/auth/status.js +0 -38
- package/dist/commands/auth/token.js +0 -19
- package/dist/commands/chat.js +0 -1416
- package/dist/commands/config/get.js +0 -64
- package/dist/commands/config/list.js +0 -46
- package/dist/commands/config/path.js +0 -37
- package/dist/commands/config/set.js +0 -132
- package/dist/commands/credentials/endpoint-list.js +0 -88
- package/dist/commands/credentials/list.js +0 -50
- package/dist/commands/credentials/policy-create.js +0 -66
- package/dist/commands/credentials/policy-delete.js +0 -33
- package/dist/commands/credentials/policy-list.js +0 -45
- package/dist/commands/credentials/policy-update.js +0 -66
- package/dist/commands/doctor.js +0 -233
- package/dist/commands/integration/connect.js +0 -76
- package/dist/commands/integration/create.js +0 -298
- package/dist/commands/integration/get.js +0 -95
- package/dist/commands/integration/list.js +0 -62
- package/dist/commands/integration/operation/create.js +0 -164
- package/dist/commands/integration/operation/list.js +0 -92
- package/dist/commands/integration/update.js +0 -139
- package/dist/commands/integration/version/build.js +0 -86
- package/dist/commands/integration/version/create.js +0 -45
- package/dist/commands/integration/version/get.js +0 -72
- package/dist/commands/integration/version/list.js +0 -45
- package/dist/commands/integration/version/publish.js +0 -79
- package/dist/commands/integration/version/test.js +0 -104
- package/dist/commands/job/get-step.js +0 -40
- package/dist/commands/job/get.js +0 -44
- package/dist/commands/mcp.js +0 -34
- package/dist/commands/session/create.js +0 -59
- package/dist/commands/session/events.js +0 -56
- package/dist/commands/session/get.js +0 -33
- package/dist/commands/session/interrupt.js +0 -33
- package/dist/commands/session/list.js +0 -59
- package/dist/commands/session/send.js +0 -54
- package/dist/commands/session/tasks.js +0 -45
- package/dist/commands/setup.js +0 -260
- package/dist/commands/trigger/activate.js +0 -41
- package/dist/commands/trigger/create.js +0 -197
- package/dist/commands/trigger/deactivate.js +0 -41
- package/dist/commands/trigger/get.js +0 -33
- package/dist/commands/trigger/list.js +0 -57
- package/dist/commands/trigger/sessions.js +0 -48
- package/dist/commands/trigger/update.js +0 -128
- package/dist/commands/version.js +0 -24
- package/dist/commands/workspace/agent/add.js +0 -114
- package/dist/commands/workspace/agent/list.js +0 -78
- package/dist/commands/workspace/agent/remove.js +0 -78
- package/dist/commands/workspace/clear.js +0 -45
- package/dist/commands/workspace/context/edit.js +0 -107
- package/dist/commands/workspace/context/get.js +0 -47
- package/dist/commands/workspace/context/list.js +0 -51
- package/dist/commands/workspace/context/publish.js +0 -42
- package/dist/commands/workspace/create.js +0 -51
- package/dist/commands/workspace/current.js +0 -63
- package/dist/commands/workspace/get.js +0 -39
- package/dist/commands/workspace/list.js +0 -70
- package/dist/commands/workspace/select.js +0 -184
- package/dist/components/AgentInstallPrompt.js +0 -97
- package/dist/components/SplashAnimation.js +0 -321
- package/dist/components/TaskView.js +0 -268
- package/dist/lib/agent-helpers.js +0 -306
- package/dist/lib/alternate-screen.js +0 -59
- package/dist/lib/api-client.js +0 -154
- package/dist/lib/api-types.js +0 -10
- package/dist/lib/auth.js +0 -284
- package/dist/lib/braille-canvas.js +0 -321
- package/dist/lib/colors.js +0 -46
- package/dist/lib/config-cache.js +0 -45
- package/dist/lib/config.js +0 -153
- package/dist/lib/did-you-mean.js +0 -144
- package/dist/lib/errors.js +0 -375
- package/dist/lib/event-filter.js +0 -91
- package/dist/lib/generated-types.js +0 -56
- package/dist/lib/git.js +0 -176
- package/dist/lib/gk.js +0 -91
- package/dist/lib/guild-config.js +0 -178
- package/dist/lib/iap.js +0 -117
- package/dist/lib/integration-helpers.js +0 -38
- package/dist/lib/loading-messages.js +0 -72
- package/dist/lib/logo.js +0 -141
- package/dist/lib/lottie-serverside.js +0 -181
- package/dist/lib/markdown.js +0 -38
- package/dist/lib/npmrc.js +0 -59
- package/dist/lib/output-mode.js +0 -54
- package/dist/lib/output.js +0 -622
- package/dist/lib/owner-helpers.js +0 -112
- package/dist/lib/polling.js +0 -76
- package/dist/lib/progress.js +0 -324
- package/dist/lib/session-events-fetch.js +0 -25
- package/dist/lib/session-events.js +0 -126
- package/dist/lib/session-polling.js +0 -166
- package/dist/lib/session-resume.js +0 -229
- package/dist/lib/spinners.js +0 -770
- package/dist/lib/splash.js +0 -42
- package/dist/lib/stdin.js +0 -91
- package/dist/lib/svg-to-braille.js +0 -76
- package/dist/lib/table.js +0 -59
- package/dist/lib/update-check.js +0 -65
- package/dist/lib/validate-input-schema.js +0 -208
- package/dist/lib/version-helpers.js +0 -137
- package/dist/lib/workspace-helpers.js +0 -49
- package/dist/mcp/resources.js +0 -67
- package/dist/mcp/server.js +0 -64
- package/dist/mcp/tools.js +0 -753
package/dist/lib/config.js
DELETED
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
// Copyright 2026 Guild.ai
|
|
2
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
-
import { readFileSync } from 'fs';
|
|
4
|
-
import path from 'path';
|
|
5
|
-
const FALLBACK_VERSION = 'unknown';
|
|
6
|
-
let cachedVersion;
|
|
7
|
-
export function getCliVersion() {
|
|
8
|
-
if (!cachedVersion) {
|
|
9
|
-
try {
|
|
10
|
-
const pkg = JSON.parse(readFileSync(path.join(__dirname, '../package.json'), 'utf-8'));
|
|
11
|
-
cachedVersion = pkg.version ?? FALLBACK_VERSION;
|
|
12
|
-
}
|
|
13
|
-
catch {
|
|
14
|
-
cachedVersion = FALLBACK_VERSION;
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
return cachedVersion;
|
|
18
|
-
}
|
|
19
|
-
export function isDevBuild() {
|
|
20
|
-
try {
|
|
21
|
-
return !__dirname.includes('node_modules');
|
|
22
|
-
}
|
|
23
|
-
catch {
|
|
24
|
-
return false;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
export function getUserAgent() {
|
|
28
|
-
try {
|
|
29
|
-
const base = `GuildCLI/${getCliVersion()}`;
|
|
30
|
-
return isDevBuild() ? `${base}/dev` : base;
|
|
31
|
-
}
|
|
32
|
-
catch {
|
|
33
|
-
return 'GuildCLI';
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* IAP configuration for shared.guildai.dev
|
|
38
|
-
*/
|
|
39
|
-
const SHARED_IAP_CONFIG = {
|
|
40
|
-
clientId: '468228011370-r08nhcdu6817hv0iol5at6f5t58sjn43.apps.googleusercontent.com',
|
|
41
|
-
serviceAccount: 'iap-auth@guildai-infra-shared.iam.gserviceaccount.com',
|
|
42
|
-
};
|
|
43
|
-
/**
|
|
44
|
-
* IAP configuration for mgorven.guildai.dev
|
|
45
|
-
*/
|
|
46
|
-
const MGORVEN_IAP_CONFIG = {
|
|
47
|
-
clientId: '1015386688686-7luftqika30hoon0i1tbkl6sbg1qg8fh.apps.googleusercontent.com',
|
|
48
|
-
serviceAccount: 'iap-auth@guildai-infra-mgorven.iam.gserviceaccount.com',
|
|
49
|
-
};
|
|
50
|
-
/**
|
|
51
|
-
* Get IAP configuration for the given URL
|
|
52
|
-
*
|
|
53
|
-
* Returns the appropriate IAP client ID and service account based on the target URL.
|
|
54
|
-
*
|
|
55
|
-
* @returns IAP config if URL is IAP-protected, null otherwise
|
|
56
|
-
*/
|
|
57
|
-
export function getIapConfig(url) {
|
|
58
|
-
try {
|
|
59
|
-
const parsed = new URL(url);
|
|
60
|
-
if (parsed.hostname === 'shared.guildai.dev') {
|
|
61
|
-
return SHARED_IAP_CONFIG;
|
|
62
|
-
}
|
|
63
|
-
if (parsed.hostname === 'mgorven.guildai.dev') {
|
|
64
|
-
return MGORVEN_IAP_CONFIG;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
catch {
|
|
68
|
-
// Invalid URL - not IAP protected
|
|
69
|
-
}
|
|
70
|
-
return null;
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* @deprecated Use getIapConfig(url).clientId instead
|
|
74
|
-
*/
|
|
75
|
-
export const IAP_CLIENT_ID = SHARED_IAP_CONFIG.clientId;
|
|
76
|
-
/**
|
|
77
|
-
* @deprecated Use getIapConfig(url).serviceAccount instead
|
|
78
|
-
*/
|
|
79
|
-
export const IAP_SERVICE_ACCOUNT = SHARED_IAP_CONFIG.serviceAccount;
|
|
80
|
-
/**
|
|
81
|
-
* GuildCore URL constants
|
|
82
|
-
*/
|
|
83
|
-
const PROD_GUILDCORE_URL = 'https://app.guild.ai/api';
|
|
84
|
-
const SHARED_GUILDCORE_URL = 'https://shared.guildai.dev/api';
|
|
85
|
-
const LOCAL_GUILDCORE_URL = 'http://localhost:5001/api';
|
|
86
|
-
/**
|
|
87
|
-
* Default GuildCore URL (production)
|
|
88
|
-
*/
|
|
89
|
-
const DEFAULT_GUILDCORE_URL = PROD_GUILDCORE_URL;
|
|
90
|
-
/**
|
|
91
|
-
* Get the Guildcore API base URL
|
|
92
|
-
*
|
|
93
|
-
* Returns the base URL for the Guildcore API with /api prefix.
|
|
94
|
-
* All public API routes (agents, workspaces, sessions, oauth, me) are under /api.
|
|
95
|
-
*
|
|
96
|
-
* Priority:
|
|
97
|
-
* 1. --shared flag (sets GUILD_USE_SHARED=1)
|
|
98
|
-
* 2. --local flag (sets GUILD_USE_LOCAL=1)
|
|
99
|
-
* 3. GUILDCORE_URL environment variable (if set)
|
|
100
|
-
* 4. GUILDCORE_PORT environment variable (constructs localhost URL)
|
|
101
|
-
* 5. Default: https://app.guild.ai/api
|
|
102
|
-
*
|
|
103
|
-
* @returns Base URL for Guildcore API (e.g., "https://app.guild.ai/api")
|
|
104
|
-
*/
|
|
105
|
-
export function getGuildcoreUrl() {
|
|
106
|
-
// Check for --shared flag (undocumented dev shortcut)
|
|
107
|
-
if (process.env.GUILD_USE_SHARED === '1') {
|
|
108
|
-
return SHARED_GUILDCORE_URL;
|
|
109
|
-
}
|
|
110
|
-
// Check for --local flag (undocumented dev shortcut)
|
|
111
|
-
if (process.env.GUILD_USE_LOCAL === '1') {
|
|
112
|
-
return LOCAL_GUILDCORE_URL;
|
|
113
|
-
}
|
|
114
|
-
// Use explicit URL if provided
|
|
115
|
-
if (process.env.GUILDCORE_URL) {
|
|
116
|
-
let url = process.env.GUILDCORE_URL.replace(/\/+$/, '');
|
|
117
|
-
if (!url.endsWith('/api')) {
|
|
118
|
-
url += '/api';
|
|
119
|
-
}
|
|
120
|
-
return url;
|
|
121
|
-
}
|
|
122
|
-
// Use localhost if port is explicitly set (for local development)
|
|
123
|
-
if (process.env.GUILDCORE_PORT) {
|
|
124
|
-
return `http://localhost:${process.env.GUILDCORE_PORT}/api`;
|
|
125
|
-
}
|
|
126
|
-
// Default to production
|
|
127
|
-
return DEFAULT_GUILDCORE_URL;
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* Get the dashboard (frontend) base URL
|
|
131
|
-
*
|
|
132
|
-
* Derives the frontend URL from the guildcore API URL by stripping /api.
|
|
133
|
-
* Used to construct clickable links to dashboard pages.
|
|
134
|
-
*/
|
|
135
|
-
export function getDashboardUrl() {
|
|
136
|
-
return getGuildcoreUrl().replace(/\/api$/, '');
|
|
137
|
-
}
|
|
138
|
-
/**
|
|
139
|
-
* Check if the given URL is an IAP-protected host
|
|
140
|
-
*
|
|
141
|
-
* IAP-protected hosts:
|
|
142
|
-
* - *.guildai.dev (shared, staging environments)
|
|
143
|
-
*/
|
|
144
|
-
export function isIapProtectedUrl(url) {
|
|
145
|
-
try {
|
|
146
|
-
const parsed = new URL(url);
|
|
147
|
-
return parsed.hostname.endsWith('.guildai.dev');
|
|
148
|
-
}
|
|
149
|
-
catch {
|
|
150
|
-
return false;
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
//# sourceMappingURL=config.js.map
|
package/dist/lib/did-you-mean.js
DELETED
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
// Copyright 2026 Guild.ai
|
|
2
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
-
/**
|
|
4
|
-
* Recursively collects all commands from the command tree.
|
|
5
|
-
* Includes both leaf commands and command groups (parents with subcommands).
|
|
6
|
-
* Aliases are added as separate entries.
|
|
7
|
-
*/
|
|
8
|
-
export function getAllCommands(cmd, prefix = '') {
|
|
9
|
-
const results = [];
|
|
10
|
-
for (const sub of cmd.commands) {
|
|
11
|
-
const name = sub.name();
|
|
12
|
-
const cmdPath = prefix ? `${prefix} ${name}` : name;
|
|
13
|
-
const description = sub.description();
|
|
14
|
-
const hasChildren = sub.commands.length > 0;
|
|
15
|
-
// Always include this command (even if it has subcommands)
|
|
16
|
-
results.push({ path: cmdPath, description, leafName: name });
|
|
17
|
-
// If this command has subcommands, also recurse into them
|
|
18
|
-
if (hasChildren) {
|
|
19
|
-
results.push(...getAllCommands(sub, cmdPath));
|
|
20
|
-
}
|
|
21
|
-
// Add aliases as separate entries
|
|
22
|
-
for (const alias of sub.aliases()) {
|
|
23
|
-
const aliasPath = prefix ? `${prefix} ${alias}` : alias;
|
|
24
|
-
results.push({ path: aliasPath, description, leafName: alias });
|
|
25
|
-
if (hasChildren) {
|
|
26
|
-
results.push(...getAllCommands(sub, aliasPath));
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
return results;
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Standard Levenshtein distance between two strings.
|
|
34
|
-
*/
|
|
35
|
-
export function levenshtein(a, b) {
|
|
36
|
-
const m = a.length;
|
|
37
|
-
const n = b.length;
|
|
38
|
-
// Use a single-row DP approach for space efficiency
|
|
39
|
-
const row = Array.from({ length: n + 1 }, (_, i) => i);
|
|
40
|
-
for (let i = 1; i <= m; i++) {
|
|
41
|
-
let prev = i - 1;
|
|
42
|
-
row[0] = i;
|
|
43
|
-
for (let j = 1; j <= n; j++) {
|
|
44
|
-
const cost = a[i - 1] === b[j - 1] ? 0 : 1;
|
|
45
|
-
const val = Math.min(row[j] + 1, // deletion
|
|
46
|
-
row[j - 1] + 1, // insertion
|
|
47
|
-
prev + cost // substitution
|
|
48
|
-
);
|
|
49
|
-
prev = row[j];
|
|
50
|
-
row[j] = val;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
return row[n];
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* Recursively disables Commander's built-in suggestion on all commands.
|
|
57
|
-
*/
|
|
58
|
-
function disableBuiltinSuggestions(cmd) {
|
|
59
|
-
cmd.showSuggestionAfterError(false);
|
|
60
|
-
for (const sub of cmd.commands) {
|
|
61
|
-
disableBuiltinSuggestions(sub);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Creates the writeErr handler that intercepts "unknown command" errors
|
|
66
|
-
* and prints cross-level suggestions.
|
|
67
|
-
*/
|
|
68
|
-
function createWriteErrHandler(program) {
|
|
69
|
-
return (str) => {
|
|
70
|
-
// Always write the original error
|
|
71
|
-
process.stderr.write(str);
|
|
72
|
-
// Check if this is an "unknown command" error
|
|
73
|
-
const match = /unknown command '([^']+)'/.exec(str);
|
|
74
|
-
if (!match) {
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
const unknown = match[1];
|
|
78
|
-
const allCommands = getAllCommands(program);
|
|
79
|
-
// Determine the typed parent context from process.argv
|
|
80
|
-
// e.g., "guild agent trigger" → typed args are ["agent", "trigger"]
|
|
81
|
-
const typedArgs = process.argv.slice(2);
|
|
82
|
-
const typedParent = typedArgs.slice(0, -1).join(' ');
|
|
83
|
-
// Score each command
|
|
84
|
-
const scored = allCommands.map((entry) => {
|
|
85
|
-
const leafName = entry.leafName;
|
|
86
|
-
// Exact leaf name match gets score 0
|
|
87
|
-
let score = leafName === unknown ? 0 : levenshtein(unknown, leafName);
|
|
88
|
-
// Context bonus: if command's parent matches typed parent, reduce score
|
|
89
|
-
const entryParts = entry.path.split(' ');
|
|
90
|
-
const entryParent = entryParts.slice(0, -1).join(' ');
|
|
91
|
-
if (entryParent === typedParent && score > 0) {
|
|
92
|
-
score -= 0.5;
|
|
93
|
-
}
|
|
94
|
-
return { ...entry, score };
|
|
95
|
-
});
|
|
96
|
-
// Filter poor matches
|
|
97
|
-
const threshold = Math.max(2, unknown.length / 2);
|
|
98
|
-
const filtered = scored.filter((s) => s.score <= threshold);
|
|
99
|
-
if (filtered.length === 0) {
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
// Sort by score, deduplicate by path
|
|
103
|
-
filtered.sort((a, b) => a.score - b.score);
|
|
104
|
-
const seen = new Set();
|
|
105
|
-
const unique = filtered.filter((entry) => {
|
|
106
|
-
if (seen.has(entry.path)) {
|
|
107
|
-
return false;
|
|
108
|
-
}
|
|
109
|
-
seen.add(entry.path);
|
|
110
|
-
return true;
|
|
111
|
-
});
|
|
112
|
-
// Print top 5 suggestions
|
|
113
|
-
const top = unique.slice(0, 5);
|
|
114
|
-
process.stderr.write('\nDid you mean?\n');
|
|
115
|
-
for (const entry of top) {
|
|
116
|
-
const cmd = `guild ${entry.path}`;
|
|
117
|
-
const padding = ' '.repeat(Math.max(2, 30 - cmd.length));
|
|
118
|
-
process.stderr.write(` ${cmd}${padding}${entry.description}\n`);
|
|
119
|
-
}
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* Recursively configures writeErr on a command and all its subcommands.
|
|
124
|
-
*/
|
|
125
|
-
function configureOutputRecursively(cmd, writeErr) {
|
|
126
|
-
cmd.configureOutput({ writeErr });
|
|
127
|
-
for (const sub of cmd.commands) {
|
|
128
|
-
configureOutputRecursively(sub, writeErr);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
/**
|
|
132
|
-
* Sets up cross-level "Did you mean?" suggestions for unknown commands.
|
|
133
|
-
*
|
|
134
|
-
* Disables Commander's built-in same-level suggestions and intercepts
|
|
135
|
-
* "unknown command" errors to search the entire command tree.
|
|
136
|
-
*/
|
|
137
|
-
export function setupUnknownCommandSuggestions(program) {
|
|
138
|
-
// Disable Commander's built-in suggestion on all commands
|
|
139
|
-
disableBuiltinSuggestions(program);
|
|
140
|
-
// Create a shared writeErr handler and apply it to all commands
|
|
141
|
-
const writeErr = createWriteErrHandler(program);
|
|
142
|
-
configureOutputRecursively(program, writeErr);
|
|
143
|
-
}
|
|
144
|
-
//# sourceMappingURL=did-you-mean.js.map
|
package/dist/lib/errors.js
DELETED
|
@@ -1,375 +0,0 @@
|
|
|
1
|
-
// Copyright 2026 Guild.ai
|
|
2
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
-
/**
|
|
4
|
-
* Standardized error handling utilities for Guild CLI
|
|
5
|
-
*/
|
|
6
|
-
import { getConfigFlag } from './config-cache.js';
|
|
7
|
-
export class GuildCLIError extends Error {
|
|
8
|
-
code;
|
|
9
|
-
details;
|
|
10
|
-
constructor(code, message, details) {
|
|
11
|
-
super(message);
|
|
12
|
-
this.code = code;
|
|
13
|
-
this.details = details;
|
|
14
|
-
this.name = 'GuildCLIError';
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Common error codes
|
|
19
|
-
*/
|
|
20
|
-
export const ErrorCodes = {
|
|
21
|
-
// Network errors
|
|
22
|
-
NETWORK_ERROR: 'NETWORK_ERROR',
|
|
23
|
-
CONN_REFUSED: 'ECONNREFUSED',
|
|
24
|
-
TIMEOUT: 'ETIMEDOUT',
|
|
25
|
-
DNS_ERROR: 'ENOTFOUND',
|
|
26
|
-
REQUEST_ABORTED: 'ECONNABORTED',
|
|
27
|
-
REQUEST_CANCELED: 'ERR_CANCELED',
|
|
28
|
-
// Auth errors
|
|
29
|
-
AUTH_FAILED: 'AUTH_FAILED',
|
|
30
|
-
AUTH_TOKEN_EXPIRED: 'AUTH_TOKEN_EXPIRED',
|
|
31
|
-
AUTH_TOKEN_INVALID: 'AUTH_TOKEN_INVALID',
|
|
32
|
-
AUTH_REQUIRED: 'AUTH_REQUIRED',
|
|
33
|
-
// IAP errors (Google Identity-Aware Proxy)
|
|
34
|
-
IAP_NOT_AUTHENTICATED: 'IAP_NOT_AUTHENTICATED',
|
|
35
|
-
IAP_GCLOUD_NOT_FOUND: 'IAP_GCLOUD_NOT_FOUND',
|
|
36
|
-
IAP_ACCESS_DENIED: 'IAP_ACCESS_DENIED',
|
|
37
|
-
// Permission errors
|
|
38
|
-
FORBIDDEN: 'FORBIDDEN',
|
|
39
|
-
// API errors
|
|
40
|
-
API_ERROR: 'API_ERROR',
|
|
41
|
-
NOT_FOUND: 'NOT_FOUND',
|
|
42
|
-
BAD_REQUEST: 'BAD_REQUEST',
|
|
43
|
-
SERVER_ERROR: 'SERVER_ERROR',
|
|
44
|
-
// Resource errors
|
|
45
|
-
RESOURCE_EXISTS: 'RESOURCE_EXISTS',
|
|
46
|
-
RESOURCE_NOT_FOUND: 'RESOURCE_NOT_FOUND',
|
|
47
|
-
// Operation errors
|
|
48
|
-
OPERATION_FAILED: 'OPERATION_FAILED',
|
|
49
|
-
TIMEOUT_ERROR: 'TIMEOUT_ERROR',
|
|
50
|
-
VALIDATION_ERROR: 'VALIDATION_ERROR',
|
|
51
|
-
};
|
|
52
|
-
/**
|
|
53
|
-
* Check if debug mode is enabled (CLI flag or config)
|
|
54
|
-
*/
|
|
55
|
-
export function isDebugMode() {
|
|
56
|
-
return process.argv.includes('--debug') || getConfigFlag('debug');
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* Log debug message if debug mode is enabled
|
|
60
|
-
*/
|
|
61
|
-
export function debug(message, ...args) {
|
|
62
|
-
if (isDebugMode()) {
|
|
63
|
-
console.error(`[DEBUG] ${message}`, ...args);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Format error for output
|
|
68
|
-
*/
|
|
69
|
-
export function formatError(error, details, code, stack, suggestions) {
|
|
70
|
-
const result = {
|
|
71
|
-
error,
|
|
72
|
-
details,
|
|
73
|
-
};
|
|
74
|
-
if (code) {
|
|
75
|
-
result.code = code;
|
|
76
|
-
}
|
|
77
|
-
if (isDebugMode() && stack) {
|
|
78
|
-
result.stack = stack;
|
|
79
|
-
}
|
|
80
|
-
if (suggestions && suggestions.length > 0) {
|
|
81
|
-
result.suggestions = suggestions;
|
|
82
|
-
}
|
|
83
|
-
return result;
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* Get user-friendly error message for common error codes
|
|
87
|
-
*/
|
|
88
|
-
export function getFriendlyErrorMessage(code, originalMessage) {
|
|
89
|
-
switch (code) {
|
|
90
|
-
case ErrorCodes.CONN_REFUSED:
|
|
91
|
-
return {
|
|
92
|
-
error: 'Connection refused',
|
|
93
|
-
details: 'Cannot connect to Guild servers.',
|
|
94
|
-
suggestions: ['Check your network connection', 'Try again in a moment'],
|
|
95
|
-
};
|
|
96
|
-
case ErrorCodes.TIMEOUT:
|
|
97
|
-
return {
|
|
98
|
-
error: 'Request timeout',
|
|
99
|
-
details: 'Server took too long to respond',
|
|
100
|
-
suggestions: [
|
|
101
|
-
'Check your network connection',
|
|
102
|
-
'Try again in a moment',
|
|
103
|
-
'Server may be experiencing high load',
|
|
104
|
-
],
|
|
105
|
-
};
|
|
106
|
-
case ErrorCodes.DNS_ERROR:
|
|
107
|
-
return {
|
|
108
|
-
error: 'DNS lookup failed',
|
|
109
|
-
details: 'Could not resolve server hostname',
|
|
110
|
-
suggestions: [
|
|
111
|
-
'Check your internet connection',
|
|
112
|
-
'Verify the server URL is correct',
|
|
113
|
-
'Check DNS settings',
|
|
114
|
-
],
|
|
115
|
-
};
|
|
116
|
-
case ErrorCodes.REQUEST_CANCELED:
|
|
117
|
-
return {
|
|
118
|
-
error: 'Request canceled',
|
|
119
|
-
details: 'The request was canceled before completion',
|
|
120
|
-
};
|
|
121
|
-
case ErrorCodes.REQUEST_ABORTED:
|
|
122
|
-
return {
|
|
123
|
-
error: 'Request aborted',
|
|
124
|
-
details: 'The connection was aborted before receiving a response',
|
|
125
|
-
suggestions: ['Check if the server is running', 'Verify network connectivity'],
|
|
126
|
-
};
|
|
127
|
-
case ErrorCodes.AUTH_TOKEN_EXPIRED:
|
|
128
|
-
return {
|
|
129
|
-
error: 'Authentication token expired',
|
|
130
|
-
details: 'Your session has expired. Please log in again.',
|
|
131
|
-
suggestions: ['Run: guild auth login'],
|
|
132
|
-
};
|
|
133
|
-
case ErrorCodes.AUTH_TOKEN_INVALID:
|
|
134
|
-
return {
|
|
135
|
-
error: 'Invalid authentication token',
|
|
136
|
-
details: 'Your authentication token is invalid or corrupted.',
|
|
137
|
-
suggestions: ['Run: guild auth logout', 'Then: guild auth login'],
|
|
138
|
-
};
|
|
139
|
-
case ErrorCodes.FORBIDDEN:
|
|
140
|
-
return {
|
|
141
|
-
error: 'Permission denied',
|
|
142
|
-
details: originalMessage || 'You do not have permission to perform this action.',
|
|
143
|
-
suggestions: [
|
|
144
|
-
'Check that you have access to this resource',
|
|
145
|
-
'If this is an organization resource, verify your membership and permissions',
|
|
146
|
-
],
|
|
147
|
-
};
|
|
148
|
-
case ErrorCodes.AUTH_REQUIRED:
|
|
149
|
-
return {
|
|
150
|
-
error: 'Authentication required',
|
|
151
|
-
details: 'This operation requires authentication.',
|
|
152
|
-
suggestions: ['Run: guild auth login'],
|
|
153
|
-
};
|
|
154
|
-
case ErrorCodes.NOT_FOUND:
|
|
155
|
-
return {
|
|
156
|
-
error: 'Resource not found',
|
|
157
|
-
details: originalMessage || 'The requested resource does not exist',
|
|
158
|
-
};
|
|
159
|
-
case ErrorCodes.SERVER_ERROR:
|
|
160
|
-
return {
|
|
161
|
-
error: 'Internal server error',
|
|
162
|
-
details: originalMessage ||
|
|
163
|
-
'The server encountered an error while processing your request.',
|
|
164
|
-
};
|
|
165
|
-
default:
|
|
166
|
-
return {
|
|
167
|
-
error: 'Operation failed',
|
|
168
|
-
details: originalMessage || 'An unexpected error occurred',
|
|
169
|
-
};
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
/**
|
|
173
|
-
* Handle axios error and return standardized error
|
|
174
|
-
*/
|
|
175
|
-
export function handleAxiosError(error) {
|
|
176
|
-
debug('Axios error:', error);
|
|
177
|
-
// Type guard for axios-like errors
|
|
178
|
-
const isAxiosError = (err) => {
|
|
179
|
-
return typeof err === 'object' && err !== null;
|
|
180
|
-
};
|
|
181
|
-
// Helper to safely extract message from unknown data
|
|
182
|
-
const getErrorMessage = (data) => {
|
|
183
|
-
// Try to extract message or error from JSON object
|
|
184
|
-
if (typeof data === 'object' && data !== null) {
|
|
185
|
-
if ('message' in data) {
|
|
186
|
-
const msg = data.message;
|
|
187
|
-
if (typeof msg === 'string')
|
|
188
|
-
return msg;
|
|
189
|
-
}
|
|
190
|
-
if ('error' in data) {
|
|
191
|
-
const err = data.error;
|
|
192
|
-
if (typeof err === 'string')
|
|
193
|
-
return err;
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
// If data is a string, return first 200 chars (likely HTML or plain text error)
|
|
197
|
-
if (typeof data === 'string' && data.length > 0) {
|
|
198
|
-
const cleaned = data.replace(/<[^>]*>/g, '').trim(); // Strip HTML tags
|
|
199
|
-
return cleaned.substring(0, 200);
|
|
200
|
-
}
|
|
201
|
-
return undefined;
|
|
202
|
-
};
|
|
203
|
-
if (!isAxiosError(error)) {
|
|
204
|
-
return formatError('Unknown error', String(error));
|
|
205
|
-
}
|
|
206
|
-
if (error.code === ErrorCodes.AUTH_REQUIRED) {
|
|
207
|
-
const friendly = getFriendlyErrorMessage(ErrorCodes.AUTH_REQUIRED, error.message || 'Authentication required');
|
|
208
|
-
return formatError(friendly.error, friendly.details, ErrorCodes.AUTH_REQUIRED, error.stack);
|
|
209
|
-
}
|
|
210
|
-
if (error.code === ErrorCodes.CONN_REFUSED) {
|
|
211
|
-
const friendly = getFriendlyErrorMessage(ErrorCodes.CONN_REFUSED, error.message || 'Connection refused');
|
|
212
|
-
return formatError(friendly.error, friendly.details, ErrorCodes.CONN_REFUSED, error.stack);
|
|
213
|
-
}
|
|
214
|
-
if (error.code === ErrorCodes.TIMEOUT) {
|
|
215
|
-
const friendly = getFriendlyErrorMessage(ErrorCodes.TIMEOUT, error.message || 'Timeout');
|
|
216
|
-
return formatError(friendly.error, friendly.details, ErrorCodes.TIMEOUT, error.stack);
|
|
217
|
-
}
|
|
218
|
-
if (error.code === ErrorCodes.DNS_ERROR) {
|
|
219
|
-
const friendly = getFriendlyErrorMessage(ErrorCodes.DNS_ERROR, error.message || 'DNS error');
|
|
220
|
-
return formatError(friendly.error, friendly.details, ErrorCodes.DNS_ERROR, error.stack);
|
|
221
|
-
}
|
|
222
|
-
if (error.code === ErrorCodes.REQUEST_CANCELED) {
|
|
223
|
-
const friendly = getFriendlyErrorMessage(ErrorCodes.REQUEST_CANCELED, error.message || 'Request canceled');
|
|
224
|
-
return formatError(friendly.error, friendly.details, ErrorCodes.REQUEST_CANCELED, error.stack);
|
|
225
|
-
}
|
|
226
|
-
if (error.code === ErrorCodes.REQUEST_ABORTED) {
|
|
227
|
-
const friendly = getFriendlyErrorMessage(ErrorCodes.REQUEST_ABORTED, error.message || 'Request aborted');
|
|
228
|
-
return formatError(friendly.error, friendly.details, ErrorCodes.REQUEST_ABORTED, error.stack);
|
|
229
|
-
}
|
|
230
|
-
if (error.response) {
|
|
231
|
-
const status = error.response.status;
|
|
232
|
-
const data = error.response.data;
|
|
233
|
-
// Check for auth errors
|
|
234
|
-
if (status === 401) {
|
|
235
|
-
const friendly = getFriendlyErrorMessage(ErrorCodes.AUTH_REQUIRED, getErrorMessage(data) || '');
|
|
236
|
-
return formatError(friendly.error, friendly.details, ErrorCodes.AUTH_REQUIRED, error.stack);
|
|
237
|
-
}
|
|
238
|
-
if (status === 403) {
|
|
239
|
-
const friendly = getFriendlyErrorMessage(ErrorCodes.FORBIDDEN, getErrorMessage(data) || '');
|
|
240
|
-
return formatError(friendly.error, friendly.details, ErrorCodes.FORBIDDEN, error.stack);
|
|
241
|
-
}
|
|
242
|
-
if (status === 404) {
|
|
243
|
-
const friendly = getFriendlyErrorMessage(ErrorCodes.NOT_FOUND, getErrorMessage(data) || '');
|
|
244
|
-
return formatError(friendly.error, friendly.details, ErrorCodes.NOT_FOUND, error.stack);
|
|
245
|
-
}
|
|
246
|
-
if (status === 409) {
|
|
247
|
-
// Resource already exists / conflict
|
|
248
|
-
return formatError('Resource already exists', getErrorMessage(data) || 'The resource you are trying to create already exists', ErrorCodes.RESOURCE_EXISTS, error.stack);
|
|
249
|
-
}
|
|
250
|
-
if (status >= 500) {
|
|
251
|
-
const friendly = getFriendlyErrorMessage(ErrorCodes.SERVER_ERROR, getErrorMessage(data) || '');
|
|
252
|
-
// Include backend traceback if available (for debugging CI issues)
|
|
253
|
-
const backendTraceback = data?.traceback;
|
|
254
|
-
const details = backendTraceback
|
|
255
|
-
? `${friendly.details}\n\nBackend traceback:\n${backendTraceback}`
|
|
256
|
-
: friendly.details;
|
|
257
|
-
return formatError(friendly.error, details, ErrorCodes.SERVER_ERROR, error.stack, friendly.suggestions);
|
|
258
|
-
}
|
|
259
|
-
// Generic API error
|
|
260
|
-
return formatError(`API error: ${status}`, getErrorMessage(data) || error.message || 'Unknown error', ErrorCodes.API_ERROR, error.stack);
|
|
261
|
-
}
|
|
262
|
-
// Pass through the actual error - don't claim it's a network error
|
|
263
|
-
return formatError('Unexpected error', error.message || 'An unknown error occurred', undefined, error.stack);
|
|
264
|
-
}
|
|
265
|
-
/**
|
|
266
|
-
* Patterns that indicate IAP authentication errors
|
|
267
|
-
*/
|
|
268
|
-
const IAP_ERROR_PATTERNS = [
|
|
269
|
-
'Not authenticated to Google Cloud',
|
|
270
|
-
'gcloud CLI not found',
|
|
271
|
-
'Access denied to service account',
|
|
272
|
-
'gcloud returned empty token',
|
|
273
|
-
];
|
|
274
|
-
/**
|
|
275
|
-
* Messages from Guildcore that indicate a real Guild auth failure.
|
|
276
|
-
* Source: python/guildcore/core/session.py and routing.py
|
|
277
|
-
*/
|
|
278
|
-
const GUILD_AUTH_FAILURE_MESSAGES = [
|
|
279
|
-
'Access token expired',
|
|
280
|
-
'Access token invalid',
|
|
281
|
-
'Session expired',
|
|
282
|
-
'Not authenticated',
|
|
283
|
-
];
|
|
284
|
-
/**
|
|
285
|
-
* Check if an error is an IAP (Google Identity-Aware Proxy) error
|
|
286
|
-
*/
|
|
287
|
-
export function isIapError(error) {
|
|
288
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
289
|
-
return IAP_ERROR_PATTERNS.some((pattern) => message.includes(pattern));
|
|
290
|
-
}
|
|
291
|
-
/**
|
|
292
|
-
* Check if an error is a Guild auth error
|
|
293
|
-
*/
|
|
294
|
-
export function isAuthError(error) {
|
|
295
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
296
|
-
return GUILD_AUTH_FAILURE_MESSAGES.some((pattern) => message.includes(pattern));
|
|
297
|
-
}
|
|
298
|
-
/**
|
|
299
|
-
* Check if a 401 response message indicates the stored auth token should be cleared.
|
|
300
|
-
* Uses exact match — only clear for known Guild auth failures.
|
|
301
|
-
*/
|
|
302
|
-
export function shouldClearAuthToken(responseMessage) {
|
|
303
|
-
if (!responseMessage)
|
|
304
|
-
return false;
|
|
305
|
-
return GUILD_AUTH_FAILURE_MESSAGES.some((msg) => msg === responseMessage);
|
|
306
|
-
}
|
|
307
|
-
/**
|
|
308
|
-
* Check if an error is fatal (should not be retried)
|
|
309
|
-
*
|
|
310
|
-
* Fatal errors include:
|
|
311
|
-
* - IAP authentication failures (need gcloud auth login)
|
|
312
|
-
* - Guild authentication failures (need guild auth login)
|
|
313
|
-
* - 4xx HTTP errors (client errors, not transient)
|
|
314
|
-
*/
|
|
315
|
-
export function isFatalError(error) {
|
|
316
|
-
// IAP and auth errors are fatal
|
|
317
|
-
if (isIapError(error) || isAuthError(error)) {
|
|
318
|
-
return true;
|
|
319
|
-
}
|
|
320
|
-
// Check for 4xx HTTP status codes (client errors)
|
|
321
|
-
if (typeof error === 'object' && error !== null) {
|
|
322
|
-
const err = error;
|
|
323
|
-
if (err.response?.status &&
|
|
324
|
-
err.response.status >= 400 &&
|
|
325
|
-
err.response.status < 500) {
|
|
326
|
-
return true;
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
return false;
|
|
330
|
-
}
|
|
331
|
-
/**
|
|
332
|
-
* Check if an error is retryable (transient network/server issues)
|
|
333
|
-
*/
|
|
334
|
-
export function isRetryableError(error) {
|
|
335
|
-
// Fatal errors should not be retried
|
|
336
|
-
if (isFatalError(error)) {
|
|
337
|
-
return false;
|
|
338
|
-
}
|
|
339
|
-
// Check for known retryable error codes
|
|
340
|
-
if (typeof error === 'object' && error !== null) {
|
|
341
|
-
const err = error;
|
|
342
|
-
return (err.code === ErrorCodes.CONN_REFUSED ||
|
|
343
|
-
err.code === ErrorCodes.TIMEOUT ||
|
|
344
|
-
err.code === ErrorCodes.DNS_ERROR ||
|
|
345
|
-
err.code === ErrorCodes.REQUEST_ABORTED ||
|
|
346
|
-
(err.response !== undefined && err.response.status >= 500));
|
|
347
|
-
}
|
|
348
|
-
return false;
|
|
349
|
-
}
|
|
350
|
-
/**
|
|
351
|
-
* Retry a function with exponential backoff
|
|
352
|
-
*/
|
|
353
|
-
export async function retry(fn, options = {}) {
|
|
354
|
-
const { maxAttempts = 3, initialDelay = 1000, maxDelay = 10000, backoffMultiplier = 2, shouldRetry = isRetryableError, } = options;
|
|
355
|
-
let lastError;
|
|
356
|
-
let delay = initialDelay;
|
|
357
|
-
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
358
|
-
try {
|
|
359
|
-
debug(`Attempt ${attempt}/${maxAttempts}`);
|
|
360
|
-
return await fn();
|
|
361
|
-
}
|
|
362
|
-
catch (error) {
|
|
363
|
-
lastError = error;
|
|
364
|
-
if (attempt === maxAttempts || !shouldRetry(error)) {
|
|
365
|
-
throw error;
|
|
366
|
-
}
|
|
367
|
-
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
368
|
-
debug(`Attempt ${attempt} failed, retrying in ${delay}ms...`, errorMsg);
|
|
369
|
-
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
370
|
-
delay = Math.min(delay * backoffMultiplier, maxDelay);
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
throw lastError;
|
|
374
|
-
}
|
|
375
|
-
//# sourceMappingURL=errors.js.map
|