@dosu/cli 0.42.0 → 0.43.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/bin/dosu.js +74 -185
- package/package.json +1 -1
package/bin/dosu.js
CHANGED
|
@@ -4759,7 +4759,7 @@ var init_dist4 = __esm(() => {
|
|
|
4759
4759
|
function getVersionString() {
|
|
4760
4760
|
return `v${VERSION}`;
|
|
4761
4761
|
}
|
|
4762
|
-
var VERSION = "0.
|
|
4762
|
+
var VERSION = "0.43.0", INSTALL_CHANNEL = "npm";
|
|
4763
4763
|
|
|
4764
4764
|
// src/debug/logger.ts
|
|
4765
4765
|
import {
|
|
@@ -11858,46 +11858,9 @@ code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; background:
|
|
|
11858
11858
|
</body>
|
|
11859
11859
|
</html>`;
|
|
11860
11860
|
}
|
|
11861
|
-
function
|
|
11862
|
-
return `<script>
|
|
11863
|
-
(function () {
|
|
11864
|
-
var tries = 0;
|
|
11865
|
-
var misses = 0;
|
|
11866
|
-
var setCopy = function (heading, msg) {
|
|
11867
|
-
var h = document.getElementById('heading');
|
|
11868
|
-
var m = document.getElementById('close-msg');
|
|
11869
|
-
if (h && heading) h.textContent = heading;
|
|
11870
|
-
if (m && msg) m.textContent = msg;
|
|
11871
|
-
};
|
|
11872
|
-
var settle = function () { setCopy(null, ${JSON.stringify(settleMsg)}); };
|
|
11873
|
-
var timer = setInterval(function () {
|
|
11874
|
-
tries += 1;
|
|
11875
|
-
if (tries > 720) { clearInterval(timer); settle(); return; }
|
|
11876
|
-
fetch('/next').then(function (res) {
|
|
11877
|
-
misses = 0;
|
|
11878
|
-
if (res.status === 200) {
|
|
11879
|
-
clearInterval(timer);
|
|
11880
|
-
res.json().then(function (body) {
|
|
11881
|
-
if (body && body.url) {
|
|
11882
|
-
setCopy("You're ready to connect your data sources", 'Redirecting...');
|
|
11883
|
-
window.location.replace(body.url);
|
|
11884
|
-
}
|
|
11885
|
-
});
|
|
11886
|
-
} else if (res.status === 410) {
|
|
11887
|
-
clearInterval(timer);
|
|
11888
|
-
settle();
|
|
11889
|
-
}
|
|
11890
|
-
}).catch(function () {
|
|
11891
|
-
misses += 1;
|
|
11892
|
-
if (misses >= 8) { clearInterval(timer); settle(); }
|
|
11893
|
-
});
|
|
11894
|
-
}, 250);
|
|
11895
|
-
})();
|
|
11896
|
-
</script>`;
|
|
11897
|
-
}
|
|
11898
|
-
function buildSuccessHtml(email, variant = "auth", withNextPoll = false) {
|
|
11861
|
+
function buildSuccessHtml(email, variant = "auth") {
|
|
11899
11862
|
const copy2 = SUCCESS_COPY[variant];
|
|
11900
|
-
const closeMsg =
|
|
11863
|
+
const closeMsg = copy2.close;
|
|
11901
11864
|
const emailLine = email ? `<p class="email">Signed in as <strong>${email.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">")}</strong></p>` : "";
|
|
11902
11865
|
return `<!DOCTYPE html>
|
|
11903
11866
|
<html lang="en">
|
|
@@ -12015,7 +11978,6 @@ h1 {
|
|
|
12015
11978
|
<span class="tip-label">Did you know?</span>
|
|
12016
11979
|
You can use Dosu to make your coding agents faster and cheaper. Just ask your agent to use Dosu to update your AGENTS.md.
|
|
12017
11980
|
</div>
|
|
12018
|
-
${withNextPoll ? buildNextPollScript(copy2.close) : ""}
|
|
12019
11981
|
</body>
|
|
12020
11982
|
</html>`;
|
|
12021
11983
|
}
|
|
@@ -12026,27 +11988,12 @@ async function startCallbackServer(opts = {}) {
|
|
|
12026
11988
|
resolveToken = resolve;
|
|
12027
11989
|
rejectToken = reject;
|
|
12028
11990
|
});
|
|
12029
|
-
let nextTarget;
|
|
12030
11991
|
const http = __require("node:http");
|
|
12031
11992
|
const httpServer = http.createServer((req, res) => {
|
|
12032
11993
|
const url = new URL(req.url ?? "/", `http://localhost`);
|
|
12033
11994
|
const cookieLen = (req.headers.cookie ?? "").length;
|
|
12034
11995
|
const ua = req.headers["user-agent"] ?? "none";
|
|
12035
11996
|
logger.debug("auth.server", `Request: ${req.method} ${url.pathname} cookie-len=${cookieLen} ua=${ua} has-token=${url.searchParams.has("access_token")}`);
|
|
12036
|
-
if (opts.nextHold && url.pathname === "/next") {
|
|
12037
|
-
if (nextTarget === undefined) {
|
|
12038
|
-
res.writeHead(204);
|
|
12039
|
-
res.end();
|
|
12040
|
-
} else if (nextTarget === null) {
|
|
12041
|
-
res.writeHead(410);
|
|
12042
|
-
res.end();
|
|
12043
|
-
} else {
|
|
12044
|
-
logger.info("auth.server", "Handing tab onward via /next");
|
|
12045
|
-
res.writeHead(200, { "Content-Type": "application/json" });
|
|
12046
|
-
res.end(JSON.stringify({ url: nextTarget }));
|
|
12047
|
-
}
|
|
12048
|
-
return;
|
|
12049
|
-
}
|
|
12050
11997
|
if (url.pathname !== "/callback") {
|
|
12051
11998
|
logger.debug("auth.server", `404: ${url.pathname}`);
|
|
12052
11999
|
res.writeHead(404, { "Content-Type": "text/plain" });
|
|
@@ -12094,7 +12041,7 @@ async function startCallbackServer(opts = {}) {
|
|
|
12094
12041
|
});
|
|
12095
12042
|
logger.info("auth.server", "Served success HTML");
|
|
12096
12043
|
res.writeHead(200, { "Content-Type": "text/html" });
|
|
12097
|
-
res.end(buildSuccessHtml(email ?? undefined, opts.successVariant ?? "auth"
|
|
12044
|
+
res.end(buildSuccessHtml(email ?? undefined, opts.successVariant ?? "auth"));
|
|
12098
12045
|
});
|
|
12099
12046
|
await new Promise((resolve) => {
|
|
12100
12047
|
httpServer.listen(0, "localhost", () => resolve());
|
|
@@ -12108,9 +12055,6 @@ async function startCallbackServer(opts = {}) {
|
|
|
12108
12055
|
close: () => {
|
|
12109
12056
|
httpServer.close();
|
|
12110
12057
|
httpServer.closeAllConnections?.();
|
|
12111
|
-
},
|
|
12112
|
-
setNext: (url) => {
|
|
12113
|
-
nextTarget = url;
|
|
12114
12058
|
}
|
|
12115
12059
|
},
|
|
12116
12060
|
tokenPromise
|
|
@@ -12205,11 +12149,9 @@ __export(exports_flow, {
|
|
|
12205
12149
|
});
|
|
12206
12150
|
async function startOAuthFlow(signal, path3 = "/cli/auth", params = {}, onAuthURL, options = {}) {
|
|
12207
12151
|
const { server, tokenPromise } = await startCallbackServer({
|
|
12208
|
-
nextHold: options.holdNext,
|
|
12209
12152
|
successVariant: options.successVariant
|
|
12210
12153
|
});
|
|
12211
12154
|
let timeoutId;
|
|
12212
|
-
let handedOver = false;
|
|
12213
12155
|
try {
|
|
12214
12156
|
const callbackURL = `http://localhost:${server.port}/callback`;
|
|
12215
12157
|
logger.debug("auth.flow", `Callback URL: ${callbackURL}`);
|
|
@@ -12217,29 +12159,26 @@ async function startOAuthFlow(signal, path3 = "/cli/auth", params = {}, onAuthUR
|
|
|
12217
12159
|
logger.info("auth.flow", `Auth URL: ${authURL}`);
|
|
12218
12160
|
options.onAuthURL?.(authURL);
|
|
12219
12161
|
let browserOpened = false;
|
|
12220
|
-
|
|
12162
|
+
const open2 = await Promise.resolve().then(() => (init_open(), exports_open));
|
|
12163
|
+
try {
|
|
12164
|
+
await open2.default(authURL);
|
|
12221
12165
|
browserOpened = true;
|
|
12222
|
-
logger.info("auth.flow", "Browser open
|
|
12223
|
-
|
|
12224
|
-
|
|
12225
|
-
|
|
12226
|
-
await open2.default(authURL);
|
|
12227
|
-
browserOpened = true;
|
|
12228
|
-
logger.info("auth.flow", "Browser open command executed");
|
|
12229
|
-
onAuthURL?.(authURL);
|
|
12230
|
-
} catch (openErr) {
|
|
12231
|
-
logger.warn("auth.flow", `Could not open browser automatically: ${openErr instanceof Error ? openErr.message : String(openErr)}`);
|
|
12232
|
-
}
|
|
12166
|
+
logger.info("auth.flow", "Browser open command executed");
|
|
12167
|
+
onAuthURL?.(authURL);
|
|
12168
|
+
} catch (openErr) {
|
|
12169
|
+
logger.warn("auth.flow", `Could not open browser automatically: ${openErr instanceof Error ? openErr.message : String(openErr)}`);
|
|
12233
12170
|
}
|
|
12234
12171
|
if (!browserOpened && !options.waitWithoutBrowser) {
|
|
12235
12172
|
logger.debug("auth.flow", "Browser unavailable — returning to caller for fallback");
|
|
12236
12173
|
return { browserOpened: false };
|
|
12237
12174
|
}
|
|
12175
|
+
const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
12176
|
+
const timeoutMinutes = Math.round(timeoutMs / 60000);
|
|
12238
12177
|
const timeout = new Promise((_2, reject) => {
|
|
12239
12178
|
timeoutId = setTimeout(() => {
|
|
12240
|
-
logger.warn("auth.flow",
|
|
12241
|
-
reject(new Error(
|
|
12242
|
-
},
|
|
12179
|
+
logger.warn("auth.flow", `Authentication timed out (${timeoutMinutes}min)`);
|
|
12180
|
+
reject(new Error(`Authentication did not complete within ${timeoutMinutes} minutes. If you finished in the browser after the timeout, just re-run the command.`));
|
|
12181
|
+
}, timeoutMs);
|
|
12243
12182
|
});
|
|
12244
12183
|
const abort = signal ? new Promise((_2, reject) => {
|
|
12245
12184
|
signal.addEventListener("abort", () => {
|
|
@@ -12249,17 +12188,11 @@ async function startOAuthFlow(signal, path3 = "/cli/auth", params = {}, onAuthUR
|
|
|
12249
12188
|
}) : new Promise(() => {});
|
|
12250
12189
|
const token = await Promise.race([tokenPromise, timeout, abort]);
|
|
12251
12190
|
logger.info("auth.flow", "Token received");
|
|
12252
|
-
if (options.holdNext) {
|
|
12253
|
-
handedOver = true;
|
|
12254
|
-
return { browserOpened: true, token, server };
|
|
12255
|
-
}
|
|
12256
12191
|
return { browserOpened: true, token };
|
|
12257
12192
|
} finally {
|
|
12258
12193
|
clearTimeout(timeoutId);
|
|
12259
|
-
|
|
12260
|
-
|
|
12261
|
-
logger.debug("auth.flow", "Cleaning up: timeout cleared, server closed");
|
|
12262
|
-
}
|
|
12194
|
+
server.close();
|
|
12195
|
+
logger.debug("auth.flow", "Cleaning up: timeout cleared, server closed");
|
|
12263
12196
|
}
|
|
12264
12197
|
}
|
|
12265
12198
|
function buildAuthURL(callbackURL, path3, extraParams) {
|
|
@@ -12267,9 +12200,11 @@ function buildAuthURL(callbackURL, path3, extraParams) {
|
|
|
12267
12200
|
const params = new URLSearchParams({ callback: callbackURL, ...extraParams });
|
|
12268
12201
|
return `${webAppURL}${path3}?${params}`;
|
|
12269
12202
|
}
|
|
12203
|
+
var DEFAULT_TIMEOUT_MS;
|
|
12270
12204
|
var init_flow = __esm(() => {
|
|
12271
12205
|
init_logger();
|
|
12272
12206
|
init_server();
|
|
12207
|
+
DEFAULT_TIMEOUT_MS = 8 * 60 * 1000;
|
|
12273
12208
|
});
|
|
12274
12209
|
|
|
12275
12210
|
// src/setup/flow.ts
|
|
@@ -12300,11 +12235,6 @@ async function runSetup(opts = {}) {
|
|
|
12300
12235
|
if (!authed)
|
|
12301
12236
|
return;
|
|
12302
12237
|
cfg = authed.cfg;
|
|
12303
|
-
const authTab = authed.authTab;
|
|
12304
|
-
const releaseAuthTab = () => {
|
|
12305
|
-
authTab?.setNext(null);
|
|
12306
|
-
authTab?.close();
|
|
12307
|
-
};
|
|
12308
12238
|
await trackCliOnboardingEvent(cfg, onboardingRunID, "cli_onboarding_auth_completed");
|
|
12309
12239
|
let apiClient = new Client(cfg);
|
|
12310
12240
|
let cloudSetupContext = null;
|
|
@@ -12317,36 +12247,41 @@ async function runSetup(opts = {}) {
|
|
|
12317
12247
|
reason: "cloud_setup_context_failed"
|
|
12318
12248
|
});
|
|
12319
12249
|
s.stop("Workspace load failed");
|
|
12320
|
-
releaseAuthTab();
|
|
12321
12250
|
return;
|
|
12322
12251
|
}
|
|
12323
12252
|
s.stop("Workspace loaded");
|
|
12324
12253
|
}
|
|
12325
12254
|
await trackCliOnboardingEvent(cfg, onboardingRunID, "cli_onboarding_started", {
|
|
12326
|
-
flow_kind: cloudSetupContext
|
|
12255
|
+
flow_kind: cloudSetupContext ? cloudSetupContext.finishedOnboarding ? "setup" : "onboarding" : "oss"
|
|
12327
12256
|
});
|
|
12328
|
-
const
|
|
12329
|
-
if (
|
|
12330
|
-
|
|
12331
|
-
|
|
12332
|
-
if (firstRunOnboarding && cloudSetupContext) {
|
|
12333
|
-
const onboarded = await stepWebOnboarding(cfg, onboardingRunID, authTab);
|
|
12334
|
-
if (!onboarded) {
|
|
12257
|
+
const needsHandshake = cfg.mode !== MODE_OSS && cloudSetupContext !== null && !cloudSetupContext.finishedOnboarding && !opts.deploymentID;
|
|
12258
|
+
if (needsHandshake) {
|
|
12259
|
+
const handshook = await stepSetupHandshake(cfg, onboardingRunID);
|
|
12260
|
+
if (!handshook) {
|
|
12335
12261
|
await trackCliOnboardingEvent(cfg, onboardingRunID, "cli_onboarding_failed", {
|
|
12336
12262
|
reason: "web_onboarding_incomplete"
|
|
12337
12263
|
});
|
|
12338
12264
|
return;
|
|
12339
12265
|
}
|
|
12340
12266
|
apiClient = new Client(cfg);
|
|
12341
|
-
const
|
|
12342
|
-
|
|
12343
|
-
if (!ok) {
|
|
12267
|
+
const refreshed = await resolveCloudSetupContext(cfg);
|
|
12268
|
+
if (refreshed === null) {
|
|
12344
12269
|
await trackCliOnboardingEvent(cfg, onboardingRunID, "cli_onboarding_failed", {
|
|
12345
|
-
reason: "
|
|
12270
|
+
reason: "cloud_setup_context_failed"
|
|
12346
12271
|
});
|
|
12347
12272
|
return;
|
|
12348
12273
|
}
|
|
12349
|
-
|
|
12274
|
+
if (!refreshed.finishedOnboarding) {
|
|
12275
|
+
log.warn("Your account still needs onboarding. Finish it in the browser at the Dosu app, then re-run `dosu setup`.");
|
|
12276
|
+
await trackCliOnboardingEvent(cfg, onboardingRunID, "cli_onboarding_failed", {
|
|
12277
|
+
reason: "onboarding_incomplete_after_handshake"
|
|
12278
|
+
});
|
|
12279
|
+
process.exitCode = 1;
|
|
12280
|
+
return;
|
|
12281
|
+
}
|
|
12282
|
+
cloudSetupContext = refreshed;
|
|
12283
|
+
}
|
|
12284
|
+
if (!cfg.active_account?.target?.deployment_id || opts.deploymentID) {
|
|
12350
12285
|
const ok = await resolveDeployment(apiClient, cfg, opts);
|
|
12351
12286
|
if (!ok) {
|
|
12352
12287
|
await trackCliOnboardingEvent(cfg, onboardingRunID, "cli_onboarding_failed", {
|
|
@@ -12521,9 +12456,13 @@ async function openBrowserForSetup(cfg, onboardingRunID) {
|
|
|
12521
12456
|
try {
|
|
12522
12457
|
const { startOAuthFlow: startOAuthFlow2 } = await Promise.resolve().then(() => (init_flow(), exports_flow));
|
|
12523
12458
|
const s = spinner();
|
|
12524
|
-
const
|
|
12459
|
+
const isCloud = cfg.mode !== MODE_OSS;
|
|
12460
|
+
const result = await startOAuthFlow2(undefined, "/cli/auth", {
|
|
12461
|
+
...isCloud ? { intent: "setup" } : {},
|
|
12462
|
+
...onboardingRunID ? { onboarding_run_id: onboardingRunID } : {}
|
|
12463
|
+
}, undefined, {
|
|
12525
12464
|
waitWithoutBrowser: true,
|
|
12526
|
-
|
|
12465
|
+
...isCloud ? { timeoutMs: SETUP_HANDSHAKE_TIMEOUT_MS } : {},
|
|
12527
12466
|
onAuthURL: (url) => {
|
|
12528
12467
|
log.message(browserFallbackHint(url));
|
|
12529
12468
|
s.start("Waiting for authentication...");
|
|
@@ -12534,7 +12473,7 @@ async function openBrowserForSetup(cfg, onboardingRunID) {
|
|
|
12534
12473
|
return null;
|
|
12535
12474
|
}
|
|
12536
12475
|
const token = result.token;
|
|
12537
|
-
s.stop("Authenticated");
|
|
12476
|
+
s.stop(token.email ? `Authenticated as ${token.email}` : "Authenticated");
|
|
12538
12477
|
logger.info("setup", "Browser auth completed");
|
|
12539
12478
|
replaceLoginSession(cfg, {
|
|
12540
12479
|
access_token: token.access_token,
|
|
@@ -12542,7 +12481,7 @@ async function openBrowserForSetup(cfg, onboardingRunID) {
|
|
|
12542
12481
|
expires_at: Math.floor(Date.now() / 1000) + token.expires_in
|
|
12543
12482
|
});
|
|
12544
12483
|
saveConfig(cfg);
|
|
12545
|
-
return { cfg
|
|
12484
|
+
return { cfg };
|
|
12546
12485
|
} catch (err) {
|
|
12547
12486
|
const msg = err instanceof Error ? err.stack ?? err.message : String(err);
|
|
12548
12487
|
logger.error("setup", `Auth failed: ${msg}`);
|
|
@@ -12565,20 +12504,19 @@ async function openBrowserForSetup(cfg, onboardingRunID) {
|
|
|
12565
12504
|
return null;
|
|
12566
12505
|
}
|
|
12567
12506
|
}
|
|
12568
|
-
async function
|
|
12569
|
-
logger.info("setup", "Step:
|
|
12570
|
-
log.info("Almost there —
|
|
12507
|
+
async function stepSetupHandshake(cfg, onboardingRunID) {
|
|
12508
|
+
logger.info("setup", "Step: setup handshake");
|
|
12509
|
+
log.info("Almost there — finish setting up in the browser and we'll pick up from here.");
|
|
12571
12510
|
const s = spinner();
|
|
12572
12511
|
try {
|
|
12573
12512
|
const { startOAuthFlow: startOAuthFlow2 } = await Promise.resolve().then(() => (init_flow(), exports_flow));
|
|
12574
|
-
const result = await startOAuthFlow2(undefined, "/
|
|
12513
|
+
const result = await startOAuthFlow2(undefined, "/cli/auth", { intent: "setup", onboarding_run_id: onboardingRunID }, undefined, {
|
|
12575
12514
|
waitWithoutBrowser: true,
|
|
12576
|
-
suppressBrowserOpen: Boolean(authTab),
|
|
12577
12515
|
successVariant: "onboarding",
|
|
12516
|
+
timeoutMs: SETUP_HANDSHAKE_TIMEOUT_MS,
|
|
12578
12517
|
onAuthURL: (url) => {
|
|
12579
|
-
authTab?.setNext(url);
|
|
12580
12518
|
log.message(browserFallbackHint(url));
|
|
12581
|
-
s.start("Waiting for
|
|
12519
|
+
s.start("Waiting for the browser...");
|
|
12582
12520
|
}
|
|
12583
12521
|
});
|
|
12584
12522
|
if (!result.browserOpened) {
|
|
@@ -12591,17 +12529,20 @@ async function stepWebOnboarding(cfg, onboardingRunID, authTab) {
|
|
|
12591
12529
|
expires_at: Math.floor(Date.now() / 1000) + result.token.expires_in
|
|
12592
12530
|
});
|
|
12593
12531
|
saveConfig(cfg);
|
|
12594
|
-
s.stop(
|
|
12595
|
-
logger.info("setup", "
|
|
12532
|
+
s.stop(result.token.email ? `Authenticated as ${result.token.email}` : "Browser setup finished");
|
|
12533
|
+
logger.info("setup", "Setup handshake completed");
|
|
12596
12534
|
return true;
|
|
12597
12535
|
} catch (err) {
|
|
12598
12536
|
const msg = err instanceof Error ? err.message : String(err);
|
|
12599
|
-
logger.warn("setup", `
|
|
12600
|
-
s.stop("
|
|
12601
|
-
|
|
12537
|
+
logger.warn("setup", `Setup handshake did not complete: ${msg}`);
|
|
12538
|
+
s.stop("Setup not completed");
|
|
12539
|
+
const { OAuthCallbackError: OAuthCallbackError2 } = await Promise.resolve().then(() => (init_errors(), exports_errors));
|
|
12540
|
+
if (err instanceof OAuthCallbackError2) {
|
|
12541
|
+
log.error(err.userMessage);
|
|
12542
|
+
return false;
|
|
12543
|
+
}
|
|
12544
|
+
log.warn("Didn't hear back from the browser. If it opened the Dosu app instead of the setup " + "wizard, your CLI and browser may be signed in to different accounts — run " + "`dosu logout`, then retry. Otherwise finish in the browser and re-run `dosu setup`.");
|
|
12602
12545
|
return false;
|
|
12603
|
-
} finally {
|
|
12604
|
-
authTab?.close();
|
|
12605
12546
|
}
|
|
12606
12547
|
}
|
|
12607
12548
|
async function resolveCloudSetupContext(cfg) {
|
|
@@ -12615,22 +12556,9 @@ async function resolveCloudSetupContext(cfg) {
|
|
|
12615
12556
|
}
|
|
12616
12557
|
bindAccountIdentity(cfg, profile.user_id);
|
|
12617
12558
|
saveConfig(cfg);
|
|
12618
|
-
if (profile.finished_onboarding === true) {
|
|
12619
|
-
return {
|
|
12620
|
-
kind: "setup",
|
|
12621
|
-
profileUserID: profile.user_id
|
|
12622
|
-
};
|
|
12623
|
-
}
|
|
12624
|
-
const targetOrg = await resolveOnboardingTargetOrg(trpc);
|
|
12625
|
-
if (!targetOrg) {
|
|
12626
|
-
log.error("Could not determine your onboarding organization.");
|
|
12627
|
-
return null;
|
|
12628
|
-
}
|
|
12629
|
-
logger.info("setup", `First-run onboarding detected for org ${targetOrg.org_id}`);
|
|
12630
12559
|
return {
|
|
12631
|
-
kind: "onboarding",
|
|
12632
12560
|
profileUserID: profile.user_id,
|
|
12633
|
-
|
|
12561
|
+
finishedOnboarding: profile.finished_onboarding === true
|
|
12634
12562
|
};
|
|
12635
12563
|
} catch (err) {
|
|
12636
12564
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -12639,53 +12567,6 @@ async function resolveCloudSetupContext(cfg) {
|
|
|
12639
12567
|
return null;
|
|
12640
12568
|
}
|
|
12641
12569
|
}
|
|
12642
|
-
async function resolveOnboardingTargetOrg(trpc) {
|
|
12643
|
-
const accessibleOrgs = await trpc.organization.getOrganizations.query();
|
|
12644
|
-
const ownerOrg = accessibleOrgs.find((org) => org.user_role === "OWNER");
|
|
12645
|
-
if (ownerOrg) {
|
|
12646
|
-
return ownerOrg;
|
|
12647
|
-
}
|
|
12648
|
-
return accessibleOrgs[0] ?? null;
|
|
12649
|
-
}
|
|
12650
|
-
async function resolveCurrentOnboardingTargetOrg(cfg) {
|
|
12651
|
-
try {
|
|
12652
|
-
const { createTypedClient: createTypedClient2 } = await Promise.resolve().then(() => (init_trpc(), exports_trpc));
|
|
12653
|
-
const trpc = createTypedClient2(cfg);
|
|
12654
|
-
const profile = await trpc.user.getCliOnboardingContext.query();
|
|
12655
|
-
if (!profile?.user_id)
|
|
12656
|
-
return null;
|
|
12657
|
-
bindAccountIdentity(cfg, profile.user_id);
|
|
12658
|
-
saveConfig(cfg);
|
|
12659
|
-
return await resolveOnboardingTargetOrg(trpc);
|
|
12660
|
-
} catch (err) {
|
|
12661
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
12662
|
-
logger.error("setup", `Failed to resolve post-onboarding organization: ${msg}`);
|
|
12663
|
-
log.error(`Could not determine your onboarding organization: ${msg}`);
|
|
12664
|
-
return null;
|
|
12665
|
-
}
|
|
12666
|
-
}
|
|
12667
|
-
async function bindOnboardingDeployment(apiClient, cfg, targetOrg) {
|
|
12668
|
-
if (!targetOrg) {
|
|
12669
|
-
log.error("Could not determine your onboarding organization.");
|
|
12670
|
-
return false;
|
|
12671
|
-
}
|
|
12672
|
-
const deployment = await resolveOnboardingDeployment(apiClient, targetOrg);
|
|
12673
|
-
if (!deployment) {
|
|
12674
|
-
log.error(`No MCP found for ${targetOrg.name}.`);
|
|
12675
|
-
return false;
|
|
12676
|
-
}
|
|
12677
|
-
cfg.mode = undefined;
|
|
12678
|
-
applyDeployment(cfg, deployment);
|
|
12679
|
-
logger.info("setup", `Bound onboarding context org=${targetOrg.org_id} deployment=${deployment.deployment_id}`);
|
|
12680
|
-
log.success(`Organization
|
|
12681
|
-
${dim(targetOrg.name)}`);
|
|
12682
|
-
return true;
|
|
12683
|
-
}
|
|
12684
|
-
async function resolveOnboardingDeployment(apiClient, targetOrg) {
|
|
12685
|
-
const deployments = await fetchDeployments(apiClient);
|
|
12686
|
-
const orgDeployments = deployments.filter((deployment) => deployment.org_id === targetOrg.org_id);
|
|
12687
|
-
return orgDeployments.find((deployment) => deployment.provider_slug === MCP_PROVIDER_SLUG) ?? orgDeployments[0] ?? null;
|
|
12688
|
-
}
|
|
12689
12570
|
async function resolveDeployment(apiClient, cfg, opts) {
|
|
12690
12571
|
if (opts.deploymentID) {
|
|
12691
12572
|
const d2 = await stepResolveDeployment(apiClient, opts.deploymentID);
|
|
@@ -12783,6 +12664,13 @@ async function stepSelectDeployment(apiClient, org) {
|
|
|
12783
12664
|
${dim(deployments[0].name)}`);
|
|
12784
12665
|
return deployments[0];
|
|
12785
12666
|
}
|
|
12667
|
+
const mcpDeployments = deployments.filter((d2) => d2.provider_slug === MCP_PROVIDER_SLUG);
|
|
12668
|
+
if (mcpDeployments.length === 1) {
|
|
12669
|
+
logger.info("setup", `Selected deployment: ${mcpDeployments[0].name} (auto, single MCP)`);
|
|
12670
|
+
log.success(`Using MCP
|
|
12671
|
+
${dim(mcpDeployments[0].name)}`);
|
|
12672
|
+
return mcpDeployments[0];
|
|
12673
|
+
}
|
|
12786
12674
|
const selected = await select({
|
|
12787
12675
|
message: "Select an MCP",
|
|
12788
12676
|
options: deployments.map((d2) => ({ label: d2.name, value: d2.deployment_id }))
|
|
@@ -12913,6 +12801,7 @@ function stepShowSummary(results) {
|
|
|
12913
12801
|
log.success("All agents already configured. No changes needed.");
|
|
12914
12802
|
}
|
|
12915
12803
|
}
|
|
12804
|
+
var SETUP_HANDSHAKE_TIMEOUT_MS = 1800000;
|
|
12916
12805
|
var init_flow2 = __esm(() => {
|
|
12917
12806
|
init_dist8();
|
|
12918
12807
|
init_client();
|
|
@@ -13808,7 +13697,7 @@ async function resolveDeployment2(client, cfg, opts) {
|
|
|
13808
13697
|
emitError({
|
|
13809
13698
|
step: "deployment",
|
|
13810
13699
|
reason: "no_deployments",
|
|
13811
|
-
agent_next_steps: "No Dosu deployments are accessible to this account.
|
|
13700
|
+
agent_next_steps: "No Dosu deployments are accessible to this account. The CLI may be signed in to a " + "different account than the user expects — have them run 'dosu logout' and retry, or " + "create a deployment at https://app.dosu.dev before retrying."
|
|
13812
13701
|
});
|
|
13813
13702
|
return { code: 1, cfg };
|
|
13814
13703
|
}
|
|
@@ -13817,7 +13706,7 @@ async function resolveDeployment2(client, cfg, opts) {
|
|
|
13817
13706
|
emitError({
|
|
13818
13707
|
step: "deployment",
|
|
13819
13708
|
reason: "no_mcp_deployment",
|
|
13820
|
-
agent_next_steps: "Account has deployments but none of them back an MCP server.
|
|
13709
|
+
agent_next_steps: "Account has deployments but none of them back an MCP server. The CLI may be signed in " + "to a different account than the user expects — have them run 'dosu logout' and retry, " + "create an MCP deployment at https://app.dosu.dev, or pass --deployment <id> to target " + "a specific deployment."
|
|
13821
13710
|
});
|
|
13822
13711
|
return { code: 1, cfg };
|
|
13823
13712
|
}
|