@dosu/cli 0.11.0-alpha.7 → 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/bin/dosu.js +223 -32
- package/package.json +2 -2
package/bin/dosu.js
CHANGED
|
@@ -4341,7 +4341,7 @@ function getSupabaseAnonKey() {
|
|
|
4341
4341
|
function getVersionString() {
|
|
4342
4342
|
return `v${VERSION}`;
|
|
4343
4343
|
}
|
|
4344
|
-
var VERSION = "0.
|
|
4344
|
+
var VERSION = "0.12.0";
|
|
4345
4345
|
|
|
4346
4346
|
// src/debug/logger.ts
|
|
4347
4347
|
import {
|
|
@@ -6258,6 +6258,88 @@ var init_dist6 = __esm(() => {
|
|
|
6258
6258
|
J2 = `${import_picocolors20.default.gray(o)} `;
|
|
6259
6259
|
});
|
|
6260
6260
|
|
|
6261
|
+
// src/setup/analytics.ts
|
|
6262
|
+
async function trackCliOnboardingEvent(cfg, onboardingRunID, event, properties = {}) {
|
|
6263
|
+
if (!cfg.access_token)
|
|
6264
|
+
return;
|
|
6265
|
+
try {
|
|
6266
|
+
const trpc = createTypedClient(cfg);
|
|
6267
|
+
await withTimeout(trpc.user.trackCliOnboardingEvent.mutate({
|
|
6268
|
+
event,
|
|
6269
|
+
properties: {
|
|
6270
|
+
...baseProperties(cfg),
|
|
6271
|
+
onboarding_run_id: onboardingRunID,
|
|
6272
|
+
...properties
|
|
6273
|
+
}
|
|
6274
|
+
}), TRACKING_TIMEOUT_MS);
|
|
6275
|
+
} catch (err) {
|
|
6276
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
6277
|
+
logger.debug("setup", `CLI onboarding analytics failed: ${event}: ${msg}`);
|
|
6278
|
+
}
|
|
6279
|
+
}
|
|
6280
|
+
async function trackCliOnboardingPreAuthEvent(onboardingRunID, event, properties = {}) {
|
|
6281
|
+
try {
|
|
6282
|
+
const trpc = createAnonymousClient();
|
|
6283
|
+
await withTimeout(trpc.user.trackCliOnboardingPreAuthEvent.mutate({
|
|
6284
|
+
event,
|
|
6285
|
+
onboarding_run_id: onboardingRunID,
|
|
6286
|
+
properties: {
|
|
6287
|
+
...baseProperties({ access_token: "", refresh_token: "", expires_at: 0 }),
|
|
6288
|
+
...properties
|
|
6289
|
+
}
|
|
6290
|
+
}), TRACKING_TIMEOUT_MS);
|
|
6291
|
+
} catch (err) {
|
|
6292
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
6293
|
+
logger.debug("setup", `CLI onboarding pre-auth analytics failed: ${event}: ${msg}`);
|
|
6294
|
+
}
|
|
6295
|
+
}
|
|
6296
|
+
function baseProperties(cfg) {
|
|
6297
|
+
return {
|
|
6298
|
+
cli_version: VERSION,
|
|
6299
|
+
platform: process.platform,
|
|
6300
|
+
arch: process.arch,
|
|
6301
|
+
mode: cfg.mode ?? "cloud",
|
|
6302
|
+
org_id: cfg.org_id,
|
|
6303
|
+
deployment_id: cfg.deployment_id,
|
|
6304
|
+
space_id: cfg.space_id
|
|
6305
|
+
};
|
|
6306
|
+
}
|
|
6307
|
+
function createAnonymousClient() {
|
|
6308
|
+
const webAppURL = getWebAppURL();
|
|
6309
|
+
if (!webAppURL) {
|
|
6310
|
+
throw new Error("Web app URL not configured");
|
|
6311
|
+
}
|
|
6312
|
+
return createTRPCClient({
|
|
6313
|
+
links: [
|
|
6314
|
+
httpLink({
|
|
6315
|
+
url: `${webAppURL}/api/trpc`,
|
|
6316
|
+
transformer: dist_default
|
|
6317
|
+
})
|
|
6318
|
+
]
|
|
6319
|
+
});
|
|
6320
|
+
}
|
|
6321
|
+
async function withTimeout(promise, timeoutMs) {
|
|
6322
|
+
let timeout;
|
|
6323
|
+
try {
|
|
6324
|
+
return await Promise.race([
|
|
6325
|
+
promise,
|
|
6326
|
+
new Promise((_3, reject) => {
|
|
6327
|
+
timeout = setTimeout(() => reject(new Error("tracking timeout")), timeoutMs);
|
|
6328
|
+
})
|
|
6329
|
+
]);
|
|
6330
|
+
} finally {
|
|
6331
|
+
if (timeout)
|
|
6332
|
+
clearTimeout(timeout);
|
|
6333
|
+
}
|
|
6334
|
+
}
|
|
6335
|
+
var TRACKING_TIMEOUT_MS = 1500;
|
|
6336
|
+
var init_analytics = __esm(() => {
|
|
6337
|
+
init_dist();
|
|
6338
|
+
init_dist4();
|
|
6339
|
+
init_trpc();
|
|
6340
|
+
init_logger();
|
|
6341
|
+
});
|
|
6342
|
+
|
|
6261
6343
|
// src/setup/styles.ts
|
|
6262
6344
|
function dim(msg) {
|
|
6263
6345
|
return import_picocolors21.default.dim(msg);
|
|
@@ -8043,7 +8125,7 @@ async function stepImportGitHubDocs(cfg, opts = {}) {
|
|
|
8043
8125
|
}
|
|
8044
8126
|
if (files.length === 0) {
|
|
8045
8127
|
M2.info("No markdown docs available to import right now. You can import them later.");
|
|
8046
|
-
return { advance: true };
|
|
8128
|
+
return { advance: true, imported: false, imported_count: 0 };
|
|
8047
8129
|
}
|
|
8048
8130
|
const repositories = buildRepositories(files);
|
|
8049
8131
|
const selected = await promptGitHubDocsImport({ repositories });
|
|
@@ -8054,7 +8136,7 @@ async function stepImportGitHubDocs(cfg, opts = {}) {
|
|
|
8054
8136
|
const fileIDs = selected;
|
|
8055
8137
|
if (fileIDs.length === 0) {
|
|
8056
8138
|
M2.info("Skipped importing docs for now. You can import them later.");
|
|
8057
|
-
return { advance: true };
|
|
8139
|
+
return { advance: true, imported: false, imported_count: 0 };
|
|
8058
8140
|
}
|
|
8059
8141
|
const knowledgeStoreID = await getKnowledgeStoreID(trpc, cfg.space_id);
|
|
8060
8142
|
if (!knowledgeStoreID) {
|
|
@@ -8073,7 +8155,7 @@ async function stepImportGitHubDocs(cfg, opts = {}) {
|
|
|
8073
8155
|
spinner.stop("Import task started");
|
|
8074
8156
|
M2.success("Import task started.");
|
|
8075
8157
|
M2.info("Your docs should finish importing in a few minutes.");
|
|
8076
|
-
return { advance: true };
|
|
8158
|
+
return { advance: true, imported: false, imported_count: 0, queued: true };
|
|
8077
8159
|
}
|
|
8078
8160
|
spinner.stop("Import task started");
|
|
8079
8161
|
logger.info("setup", `Watching import task ${taskID}`);
|
|
@@ -8085,10 +8167,23 @@ async function stepImportGitHubDocs(cfg, opts = {}) {
|
|
|
8085
8167
|
progressSpinner.stop("Stopped watching import progress");
|
|
8086
8168
|
M2.info(`The import is still running in the background.
|
|
8087
8169
|
Check status later with: dosu docs import-status ${taskID}`);
|
|
8088
|
-
return {
|
|
8170
|
+
return {
|
|
8171
|
+
advance: true,
|
|
8172
|
+
imported: false,
|
|
8173
|
+
imported_count: 0,
|
|
8174
|
+
queued: true,
|
|
8175
|
+
task_id: taskID
|
|
8176
|
+
};
|
|
8089
8177
|
}
|
|
8090
8178
|
handleImportCompletion(finalStatus, progressSpinner);
|
|
8091
|
-
|
|
8179
|
+
const importedCount = finalStatus.detail?.completed ?? 0;
|
|
8180
|
+
return {
|
|
8181
|
+
advance: true,
|
|
8182
|
+
imported: importedCount > 0,
|
|
8183
|
+
imported_count: importedCount,
|
|
8184
|
+
failed_count: finalStatus.detail?.failed ?? 0,
|
|
8185
|
+
task_id: taskID
|
|
8186
|
+
};
|
|
8092
8187
|
} catch (err) {
|
|
8093
8188
|
spinner.stop("Failed");
|
|
8094
8189
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -8533,13 +8628,13 @@ var exports_flow = {};
|
|
|
8533
8628
|
__export(exports_flow, {
|
|
8534
8629
|
startOAuthFlow: () => startOAuthFlow
|
|
8535
8630
|
});
|
|
8536
|
-
async function startOAuthFlow(signal, path2 = "/cli/auth") {
|
|
8631
|
+
async function startOAuthFlow(signal, path2 = "/cli/auth", params = {}) {
|
|
8537
8632
|
const { server, tokenPromise } = await startCallbackServer();
|
|
8538
8633
|
let timeoutId;
|
|
8539
8634
|
try {
|
|
8540
8635
|
const callbackURL = `http://localhost:${server.port}/callback`;
|
|
8541
8636
|
logger.debug("auth.flow", `Callback URL: ${callbackURL}`);
|
|
8542
|
-
const authURL = buildAuthURL(callbackURL, path2);
|
|
8637
|
+
const authURL = buildAuthURL(callbackURL, path2, params);
|
|
8543
8638
|
logger.info("auth.flow", `Auth URL: ${authURL}`);
|
|
8544
8639
|
const open2 = await Promise.resolve().then(() => (init_open(), exports_open));
|
|
8545
8640
|
await open2.default(authURL);
|
|
@@ -8565,9 +8660,9 @@ async function startOAuthFlow(signal, path2 = "/cli/auth") {
|
|
|
8565
8660
|
logger.debug("auth.flow", "Cleaning up: timeout cleared, server closed");
|
|
8566
8661
|
}
|
|
8567
8662
|
}
|
|
8568
|
-
function buildAuthURL(callbackURL, path2) {
|
|
8663
|
+
function buildAuthURL(callbackURL, path2, extraParams) {
|
|
8569
8664
|
const webAppURL = getWebAppURL();
|
|
8570
|
-
const params = new URLSearchParams({ callback: callbackURL });
|
|
8665
|
+
const params = new URLSearchParams({ callback: callbackURL, ...extraParams });
|
|
8571
8666
|
return `${webAppURL}${path2}?${params}`;
|
|
8572
8667
|
}
|
|
8573
8668
|
var init_flow = __esm(() => {
|
|
@@ -8586,21 +8681,28 @@ __export(exports_flow2, {
|
|
|
8586
8681
|
runInstallSkill: () => runInstallSkill,
|
|
8587
8682
|
isStdioOnly: () => isStdioOnly
|
|
8588
8683
|
});
|
|
8684
|
+
import { randomUUID } from "node:crypto";
|
|
8589
8685
|
import { existsSync as existsSync9 } from "node:fs";
|
|
8590
8686
|
import { join as join19 } from "node:path";
|
|
8591
8687
|
async function runSetup(opts = {}) {
|
|
8688
|
+
const onboardingRunID = randomUUID();
|
|
8592
8689
|
logger.info("setup", `Setup flow started${opts.deploymentID ? ` deployment=${opts.deploymentID}` : ""}${opts.mode ? ` mode=${opts.mode}` : ""}`);
|
|
8593
8690
|
Ie("Dosu CLI Setup");
|
|
8691
|
+
await trackCliOnboardingPreAuthEvent(onboardingRunID, "cli_onboarding_launch_attempted", {
|
|
8692
|
+
has_deployment_option: Boolean(opts.deploymentID),
|
|
8693
|
+
mode_option: opts.mode
|
|
8694
|
+
});
|
|
8594
8695
|
let cfg = loadConfig();
|
|
8595
8696
|
applyModeOverride(cfg, opts);
|
|
8596
8697
|
if (opts.deploymentID) {
|
|
8597
8698
|
cfg.mode = undefined;
|
|
8598
8699
|
saveConfig(cfg);
|
|
8599
8700
|
}
|
|
8600
|
-
const authedCfg = await stepAuthenticate(cfg);
|
|
8701
|
+
const authedCfg = await stepAuthenticate(cfg, onboardingRunID);
|
|
8601
8702
|
if (!authedCfg)
|
|
8602
8703
|
return;
|
|
8603
8704
|
cfg = authedCfg;
|
|
8705
|
+
await trackCliOnboardingEvent(cfg, onboardingRunID, "cli_onboarding_auth_completed");
|
|
8604
8706
|
const apiClient = new Client(cfg);
|
|
8605
8707
|
let cloudSetupContext = null;
|
|
8606
8708
|
if (cfg.mode !== MODE_OSS) {
|
|
@@ -8608,46 +8710,101 @@ async function runSetup(opts = {}) {
|
|
|
8608
8710
|
s.start("Loading your workspace...");
|
|
8609
8711
|
cloudSetupContext = await resolveCloudSetupContext(cfg);
|
|
8610
8712
|
if (!cloudSetupContext) {
|
|
8713
|
+
await trackCliOnboardingEvent(cfg, onboardingRunID, "cli_onboarding_failed", {
|
|
8714
|
+
reason: "cloud_setup_context_failed"
|
|
8715
|
+
});
|
|
8611
8716
|
s.stop("Workspace load failed");
|
|
8612
8717
|
return;
|
|
8613
8718
|
}
|
|
8614
8719
|
s.stop("Workspace loaded");
|
|
8615
8720
|
}
|
|
8721
|
+
await trackCliOnboardingEvent(cfg, onboardingRunID, "cli_onboarding_started", {
|
|
8722
|
+
flow_kind: cloudSetupContext?.kind ?? "oss"
|
|
8723
|
+
});
|
|
8616
8724
|
if (cfg.mode !== MODE_OSS && cloudSetupContext?.kind === "onboarding") {
|
|
8617
8725
|
const ok = await bindOnboardingDeployment(apiClient, cfg, cloudSetupContext.targetOrg ?? null);
|
|
8618
|
-
if (!ok)
|
|
8726
|
+
if (!ok) {
|
|
8727
|
+
await trackCliOnboardingEvent(cfg, onboardingRunID, "cli_onboarding_failed", {
|
|
8728
|
+
reason: "onboarding_deployment_failed"
|
|
8729
|
+
});
|
|
8619
8730
|
return;
|
|
8731
|
+
}
|
|
8620
8732
|
} else if (!cfg.deployment_id || opts.deploymentID) {
|
|
8621
8733
|
const ok = await resolveDeployment(apiClient, cfg, opts);
|
|
8622
|
-
if (!ok)
|
|
8734
|
+
if (!ok) {
|
|
8735
|
+
await trackCliOnboardingEvent(cfg, onboardingRunID, "cli_onboarding_failed", {
|
|
8736
|
+
reason: "deployment_resolution_failed"
|
|
8737
|
+
});
|
|
8623
8738
|
return;
|
|
8739
|
+
}
|
|
8624
8740
|
}
|
|
8625
8741
|
const apiKey = await stepMintAPIKey(apiClient, cfg);
|
|
8626
|
-
if (!apiKey)
|
|
8742
|
+
if (!apiKey) {
|
|
8743
|
+
await trackCliOnboardingEvent(cfg, onboardingRunID, "cli_onboarding_failed", {
|
|
8744
|
+
reason: "api_key_failed"
|
|
8745
|
+
});
|
|
8627
8746
|
return;
|
|
8747
|
+
}
|
|
8628
8748
|
cfg.api_key = apiKey;
|
|
8629
8749
|
saveConfig(cfg);
|
|
8630
8750
|
const choices = await stepOneShotConfirm({
|
|
8631
8751
|
includeGitHub: cloudSetupContext?.kind === "onboarding"
|
|
8632
8752
|
});
|
|
8633
|
-
if (!choices)
|
|
8753
|
+
if (!choices) {
|
|
8754
|
+
await trackCliOnboardingEvent(cfg, onboardingRunID, "cli_onboarding_cancelled", {
|
|
8755
|
+
reason: "options_cancelled"
|
|
8756
|
+
});
|
|
8634
8757
|
return;
|
|
8758
|
+
}
|
|
8759
|
+
await trackCliOnboardingEvent(cfg, onboardingRunID, "cli_onboarding_options_selected", {
|
|
8760
|
+
configure_mcp: choices.configureMcp,
|
|
8761
|
+
install_skill: choices.installSkill,
|
|
8762
|
+
connect_github: choices.connectGitHub
|
|
8763
|
+
});
|
|
8635
8764
|
let mcpConfiguredThisRun = false;
|
|
8765
|
+
let mcpCompleted = false;
|
|
8766
|
+
let skillCompleted = false;
|
|
8767
|
+
let docsImported = false;
|
|
8636
8768
|
if (choices.configureMcp) {
|
|
8637
8769
|
const configured = await stepConfigureMcpTools(cfg);
|
|
8638
|
-
if (configured === null)
|
|
8770
|
+
if (configured === null) {
|
|
8771
|
+
await trackCliOnboardingEvent(cfg, onboardingRunID, "cli_onboarding_cancelled", {
|
|
8772
|
+
reason: "mcp_selection_cancelled"
|
|
8773
|
+
});
|
|
8639
8774
|
return;
|
|
8775
|
+
}
|
|
8640
8776
|
mcpConfiguredThisRun = configured.some((r) => r.action === "install" || r.action === "skip");
|
|
8777
|
+
const configuredProviders = configured.filter((r) => (r.action === "install" || r.action === "skip") && !r.error);
|
|
8778
|
+
mcpCompleted = configuredProviders.length > 0;
|
|
8779
|
+
if (mcpCompleted) {
|
|
8780
|
+
await trackCliOnboardingEvent(cfg, onboardingRunID, "cli_onboarding_mcp_configured", {
|
|
8781
|
+
provider_count: configuredProviders.length,
|
|
8782
|
+
providers: configuredProviders.map((r) => r.provider.id())
|
|
8783
|
+
});
|
|
8784
|
+
}
|
|
8641
8785
|
}
|
|
8642
8786
|
if (choices.installSkill) {
|
|
8643
|
-
await runInstallSkill();
|
|
8787
|
+
skillCompleted = await runInstallSkill();
|
|
8788
|
+
if (skillCompleted) {
|
|
8789
|
+
await trackCliOnboardingEvent(cfg, onboardingRunID, "cli_onboarding_skill_installed");
|
|
8790
|
+
}
|
|
8644
8791
|
}
|
|
8645
8792
|
let githubOnboardingDone = !choices.connectGitHub;
|
|
8646
8793
|
if (choices.connectGitHub && cloudSetupContext?.kind === "onboarding") {
|
|
8647
8794
|
const { stepConnectGitHubRepo: stepConnectGitHubRepo2 } = await Promise.resolve().then(() => (init_github_step(), exports_github_step));
|
|
8648
8795
|
const connectResult = await stepConnectGitHubRepo2(cfg);
|
|
8649
|
-
if (!connectResult.advance)
|
|
8796
|
+
if (!connectResult.advance) {
|
|
8797
|
+
await trackCliOnboardingEvent(cfg, onboardingRunID, "cli_onboarding_cancelled", {
|
|
8798
|
+
reason: "github_connect_not_advanced",
|
|
8799
|
+
has_connected_repo: connectResult.has_connected_repo
|
|
8800
|
+
});
|
|
8650
8801
|
return;
|
|
8802
|
+
}
|
|
8803
|
+
if (connectResult.has_connected_repo || (connectResult.created_data_source_ids?.length ?? 0) > 0) {
|
|
8804
|
+
await trackCliOnboardingEvent(cfg, onboardingRunID, "cli_onboarding_github_connected", {
|
|
8805
|
+
created_data_source_count: connectResult.created_data_source_ids?.length ?? 0
|
|
8806
|
+
});
|
|
8807
|
+
}
|
|
8651
8808
|
if (connectResult.space_id && !cfg.space_id) {
|
|
8652
8809
|
cfg.space_id = connectResult.space_id;
|
|
8653
8810
|
saveConfig(cfg);
|
|
@@ -8657,8 +8814,24 @@ async function runSetup(opts = {}) {
|
|
|
8657
8814
|
waitForFreshDocs: Boolean(connectResult.deployment_id),
|
|
8658
8815
|
expectedDataSourceIds: connectResult.created_data_source_ids
|
|
8659
8816
|
});
|
|
8660
|
-
if (!importResult.advance)
|
|
8817
|
+
if (!importResult.advance) {
|
|
8818
|
+
await trackCliOnboardingEvent(cfg, onboardingRunID, "cli_onboarding_failed", {
|
|
8819
|
+
reason: "github_docs_import_failed"
|
|
8820
|
+
});
|
|
8661
8821
|
return;
|
|
8822
|
+
}
|
|
8823
|
+
docsImported = importResult.imported === true && (importResult.imported_count ?? 0) > 0;
|
|
8824
|
+
if (docsImported) {
|
|
8825
|
+
await trackCliOnboardingEvent(cfg, onboardingRunID, "cli_onboarding_docs_imported", {
|
|
8826
|
+
imported_count: importResult.imported_count ?? 0,
|
|
8827
|
+
failed_count: importResult.failed_count ?? 0,
|
|
8828
|
+
task_id: importResult.task_id
|
|
8829
|
+
});
|
|
8830
|
+
await trackCliOnboardingEvent(cfg, onboardingRunID, "cli_onboarding_activated", {
|
|
8831
|
+
imported_count: importResult.imported_count ?? 0,
|
|
8832
|
+
failed_count: importResult.failed_count ?? 0
|
|
8833
|
+
});
|
|
8834
|
+
}
|
|
8662
8835
|
githubOnboardingDone = true;
|
|
8663
8836
|
}
|
|
8664
8837
|
const shouldCompleteRemoteOnboarding = cloudSetupContext?.kind === "onboarding" && githubOnboardingDone;
|
|
@@ -8684,6 +8857,13 @@ async function runSetup(opts = {}) {
|
|
|
8684
8857
|
hasAgentsMd: existsSync9(join19(process.cwd(), "AGENTS.md"))
|
|
8685
8858
|
});
|
|
8686
8859
|
}
|
|
8860
|
+
if (mcpCompleted || skillCompleted || docsImported) {
|
|
8861
|
+
await trackCliOnboardingEvent(cfg, onboardingRunID, "cli_onboarding_completed", {
|
|
8862
|
+
completed_mcp: mcpCompleted,
|
|
8863
|
+
completed_skill: skillCompleted,
|
|
8864
|
+
imported_docs: docsImported
|
|
8865
|
+
});
|
|
8866
|
+
}
|
|
8687
8867
|
if (cfg.mode === MODE_OSS) {
|
|
8688
8868
|
Se("Setup complete! Using open-source libraries only.\n\nTips: Run `dosu setup --mode cloud` to connect your own repos.");
|
|
8689
8869
|
} else {
|
|
@@ -8767,7 +8947,7 @@ async function runInstallSkill() {
|
|
|
8767
8947
|
return false;
|
|
8768
8948
|
}
|
|
8769
8949
|
}
|
|
8770
|
-
async function stepAuthenticate(existingCfg) {
|
|
8950
|
+
async function stepAuthenticate(existingCfg, onboardingRunID) {
|
|
8771
8951
|
logger.info("setup", "Step: authenticate");
|
|
8772
8952
|
const cfg = existingCfg ?? loadConfig();
|
|
8773
8953
|
if (cfg.access_token) {
|
|
@@ -8798,16 +8978,25 @@ async function stepAuthenticate(existingCfg) {
|
|
|
8798
8978
|
}
|
|
8799
8979
|
}
|
|
8800
8980
|
const shouldLogin = await ye({ message: "Open browser to log in?" });
|
|
8801
|
-
if (pD(shouldLogin) || !shouldLogin)
|
|
8981
|
+
if (pD(shouldLogin) || !shouldLogin) {
|
|
8982
|
+
if (onboardingRunID) {
|
|
8983
|
+
await trackCliOnboardingPreAuthEvent(onboardingRunID, "cli_onboarding_auth_cancelled", {
|
|
8984
|
+
reason: pD(shouldLogin) ? "prompt_cancelled" : "login_declined"
|
|
8985
|
+
});
|
|
8986
|
+
}
|
|
8802
8987
|
return null;
|
|
8803
|
-
|
|
8988
|
+
}
|
|
8989
|
+
if (onboardingRunID) {
|
|
8990
|
+
await trackCliOnboardingPreAuthEvent(onboardingRunID, "cli_onboarding_auth_started");
|
|
8991
|
+
}
|
|
8992
|
+
return await openBrowserForSetup(cfg, onboardingRunID);
|
|
8804
8993
|
}
|
|
8805
|
-
async function openBrowserForSetup(cfg) {
|
|
8994
|
+
async function openBrowserForSetup(cfg, onboardingRunID) {
|
|
8806
8995
|
try {
|
|
8807
8996
|
const { startOAuthFlow: startOAuthFlow2 } = await Promise.resolve().then(() => (init_flow(), exports_flow));
|
|
8808
8997
|
const s = Y2();
|
|
8809
8998
|
s.start("Waiting for authentication...");
|
|
8810
|
-
const token = await startOAuthFlow2(undefined, "/cli/auth");
|
|
8999
|
+
const token = await startOAuthFlow2(undefined, "/cli/auth", onboardingRunID ? { onboarding_run_id: onboardingRunID } : {});
|
|
8811
9000
|
s.stop("Authenticated");
|
|
8812
9001
|
logger.info("setup", "Browser auth completed");
|
|
8813
9002
|
cfg.access_token = token.access_token;
|
|
@@ -8819,6 +9008,11 @@ async function openBrowserForSetup(cfg) {
|
|
|
8819
9008
|
const msg = err instanceof Error ? err.stack ?? err.message : String(err);
|
|
8820
9009
|
logger.error("setup", `Auth failed: ${msg}`);
|
|
8821
9010
|
M2.error(`Authentication failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
9011
|
+
if (onboardingRunID) {
|
|
9012
|
+
await trackCliOnboardingPreAuthEvent(onboardingRunID, "cli_onboarding_auth_failed", {
|
|
9013
|
+
reason: err instanceof Error ? err.message : String(err)
|
|
9014
|
+
});
|
|
9015
|
+
}
|
|
8822
9016
|
return null;
|
|
8823
9017
|
}
|
|
8824
9018
|
}
|
|
@@ -8856,14 +9050,11 @@ async function resolveCloudSetupContext(cfg) {
|
|
|
8856
9050
|
}
|
|
8857
9051
|
}
|
|
8858
9052
|
async function resolveOnboardingTargetOrg(trpc) {
|
|
8859
|
-
const ownerOrgs = await trpc.organization.getOrganizations.query({
|
|
8860
|
-
userRole: "OWNER",
|
|
8861
|
-
exact: true
|
|
8862
|
-
});
|
|
8863
|
-
if (ownerOrgs.length > 0) {
|
|
8864
|
-
return ownerOrgs[0];
|
|
8865
|
-
}
|
|
8866
9053
|
const accessibleOrgs = await trpc.organization.getOrganizations.query();
|
|
9054
|
+
const ownerOrg = accessibleOrgs.find((org) => org.user_role === "OWNER");
|
|
9055
|
+
if (ownerOrg) {
|
|
9056
|
+
return ownerOrg;
|
|
9057
|
+
}
|
|
8867
9058
|
return accessibleOrgs[0] ?? null;
|
|
8868
9059
|
}
|
|
8869
9060
|
async function bindOnboardingDeployment(apiClient, cfg, targetOrg) {
|
|
@@ -9142,6 +9333,7 @@ var init_flow2 = __esm(() => {
|
|
|
9142
9333
|
init_config();
|
|
9143
9334
|
init_logger();
|
|
9144
9335
|
init_providers();
|
|
9336
|
+
init_analytics();
|
|
9145
9337
|
init_styles();
|
|
9146
9338
|
});
|
|
9147
9339
|
|
|
@@ -9379,7 +9571,6 @@ function analyticsCommand() {
|
|
|
9379
9571
|
["Low Confidence", String(stats.byConfidence.low)],
|
|
9380
9572
|
["Positive Reactions", String(stats.reactions.totalPositive)],
|
|
9381
9573
|
["Negative Reactions", String(stats.reactions.totalNegative)],
|
|
9382
|
-
["Reaction Rate", pct(stats.reactions.reactionRate)],
|
|
9383
9574
|
["Positive Rate", pct(stats.reactions.positiveRate)]
|
|
9384
9575
|
], { rawData: stats });
|
|
9385
9576
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dosu/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Dosu CLI - Manage MCP servers for AI tools",
|
|
6
6
|
"license": "MIT",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
50
|
"@clack/prompts": "^0.10.0",
|
|
51
|
-
"@dosu/api-types": "0.0.
|
|
51
|
+
"@dosu/api-types": "0.0.7",
|
|
52
52
|
"commander": "^13.1.0",
|
|
53
53
|
"open": "^10.1.0",
|
|
54
54
|
"picocolors": "^1.1.1",
|