@dosu/cli 0.11.0-alpha.5 → 0.11.0-alpha.6
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 +96 -33
- package/package.json +1 -1
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.11.0-alpha.
|
|
4344
|
+
var VERSION = "0.11.0-alpha.6";
|
|
4345
4345
|
|
|
4346
4346
|
// src/debug/logger.ts
|
|
4347
4347
|
import {
|
|
@@ -6439,12 +6439,13 @@ function visibleOptions(cursor, options, maxItems) {
|
|
|
6439
6439
|
return { kind: "option", index: start + index };
|
|
6440
6440
|
});
|
|
6441
6441
|
}
|
|
6442
|
-
var import_picocolors22, ACTION_ARROW, ADD_REPOSITORIES_VALUE = "__add_repositories__", GitHubRepoPrompt;
|
|
6442
|
+
var import_picocolors22, ACTION_ARROW, SEPARATOR_LINE, ADD_REPOSITORIES_VALUE = "__add_repositories__", REFRESH_LIST_VALUE = "__refresh_list__", GitHubRepoPrompt;
|
|
6443
6443
|
var init_github_repo_prompt = __esm(() => {
|
|
6444
6444
|
init_dist5();
|
|
6445
6445
|
init_prompt_symbols();
|
|
6446
6446
|
import_picocolors22 = __toESM(require_picocolors(), 1);
|
|
6447
6447
|
ACTION_ARROW = symbol("→", ">");
|
|
6448
|
+
SEPARATOR_LINE = "─".repeat(30);
|
|
6448
6449
|
GitHubRepoPrompt = class GitHubRepoPrompt extends x {
|
|
6449
6450
|
options;
|
|
6450
6451
|
message;
|
|
@@ -6461,7 +6462,8 @@ var init_github_repo_prompt = __esm(() => {
|
|
|
6461
6462
|
this.options = options;
|
|
6462
6463
|
this.maxItems = maxItems;
|
|
6463
6464
|
this.selected = initialValues.filter((value) => options.some((option) => option.kind === "repo" && option.value === value));
|
|
6464
|
-
|
|
6465
|
+
const initialCursor = this.options.findIndex((option) => option.kind === "repo" && this.selected.includes(option.value));
|
|
6466
|
+
this.cursor = initialCursor >= 0 ? initialCursor : this.firstFocusableIndex();
|
|
6465
6467
|
this.syncValue();
|
|
6466
6468
|
this.on("key", (key) => {
|
|
6467
6469
|
if (key === "a") {
|
|
@@ -6473,11 +6475,11 @@ var init_github_repo_prompt = __esm(() => {
|
|
|
6473
6475
|
switch (key) {
|
|
6474
6476
|
case "left":
|
|
6475
6477
|
case "up":
|
|
6476
|
-
this.cursor = this.
|
|
6478
|
+
this.cursor = this.advanceCursor(-1);
|
|
6477
6479
|
break;
|
|
6478
6480
|
case "down":
|
|
6479
6481
|
case "right":
|
|
6480
|
-
this.cursor = this.
|
|
6482
|
+
this.cursor = this.advanceCursor(1);
|
|
6481
6483
|
break;
|
|
6482
6484
|
case "space":
|
|
6483
6485
|
this.toggleCurrent();
|
|
@@ -6486,6 +6488,22 @@ var init_github_repo_prompt = __esm(() => {
|
|
|
6486
6488
|
this.syncValue();
|
|
6487
6489
|
});
|
|
6488
6490
|
}
|
|
6491
|
+
firstFocusableIndex() {
|
|
6492
|
+
const idx = this.options.findIndex((option) => option.kind !== "separator");
|
|
6493
|
+
return idx >= 0 ? idx : 0;
|
|
6494
|
+
}
|
|
6495
|
+
advanceCursor(direction) {
|
|
6496
|
+
const total = this.options.length;
|
|
6497
|
+
if (total === 0)
|
|
6498
|
+
return 0;
|
|
6499
|
+
let next = this.cursor;
|
|
6500
|
+
for (let i = 0;i < total; i++) {
|
|
6501
|
+
next = (next + direction + total) % total;
|
|
6502
|
+
if (this.options[next].kind !== "separator")
|
|
6503
|
+
return next;
|
|
6504
|
+
}
|
|
6505
|
+
return this.cursor;
|
|
6506
|
+
}
|
|
6489
6507
|
get currentOption() {
|
|
6490
6508
|
return this.options[this.cursor] ?? this.options[0];
|
|
6491
6509
|
}
|
|
@@ -6493,10 +6511,11 @@ var init_github_repo_prompt = __esm(() => {
|
|
|
6493
6511
|
this.value = this.currentOption.kind === "action" ? this.currentOption.value : [...this.selected];
|
|
6494
6512
|
}
|
|
6495
6513
|
toggleCurrent() {
|
|
6496
|
-
|
|
6514
|
+
const current = this.currentOption;
|
|
6515
|
+
if (current.kind !== "repo")
|
|
6497
6516
|
return;
|
|
6498
|
-
const selected = this.selected.includes(
|
|
6499
|
-
this.selected = selected ? this.selected.filter((value) => value !==
|
|
6517
|
+
const selected = this.selected.includes(current.value);
|
|
6518
|
+
this.selected = selected ? this.selected.filter((value) => value !== current.value) : [...this.selected, current.value];
|
|
6500
6519
|
}
|
|
6501
6520
|
toggleAll() {
|
|
6502
6521
|
const repoValues = this.options.filter((option) => option.kind === "repo").map((option) => option.value);
|
|
@@ -6514,12 +6533,14 @@ ${symbolByState} ${this.message}
|
|
|
6514
6533
|
return `${header}${import_picocolors22.default.gray(BAR)}`;
|
|
6515
6534
|
}
|
|
6516
6535
|
const body = visibleOptions(this.cursor, this.options, this.maxItems).map((option) => {
|
|
6517
|
-
const actualIndex = option.kind === "ellipsis" ? -1 : option.index;
|
|
6518
6536
|
if (option.kind === "ellipsis") {
|
|
6519
6537
|
return `${import_picocolors22.default.gray(BAR)} ${import_picocolors22.default.dim(ELLIPSIS)}`;
|
|
6520
6538
|
}
|
|
6521
|
-
const
|
|
6522
|
-
|
|
6539
|
+
const current = this.options[option.index];
|
|
6540
|
+
if (current.kind === "separator") {
|
|
6541
|
+
return `${import_picocolors22.default.gray(BAR)} ${import_picocolors22.default.dim(SEPARATOR_LINE)}`;
|
|
6542
|
+
}
|
|
6543
|
+
const isActive = option.index === this.cursor;
|
|
6523
6544
|
const marker = current.kind === "action" ? isActive ? import_picocolors22.default.cyan(ACTION_ARROW) : import_picocolors22.default.dim(ACTION_ARROW) : this.selected.includes(current.value) ? isActive ? import_picocolors22.default.cyan(CHECKBOX_ON) : CHECKBOX_ON : isActive ? import_picocolors22.default.cyan(CHECKBOX_OFF) : CHECKBOX_OFF;
|
|
6524
6545
|
const label = isActive ? import_picocolors22.default.cyan(current.label) : current.label;
|
|
6525
6546
|
const hint = current.hint ? ` ${import_picocolors22.default.dim(`(${current.hint})`)}` : "";
|
|
@@ -6530,9 +6551,12 @@ ${symbolByState} ${this.message}
|
|
|
6530
6551
|
${import_picocolors22.default.cyan(FOOTER)}`;
|
|
6531
6552
|
}
|
|
6532
6553
|
submitLabel() {
|
|
6533
|
-
if (this.value ===
|
|
6534
|
-
const
|
|
6535
|
-
|
|
6554
|
+
if (typeof this.value === "string") {
|
|
6555
|
+
const matched = this.options.find((option) => option.kind === "action" && option.value === this.value);
|
|
6556
|
+
if (matched && matched.kind === "action")
|
|
6557
|
+
return matched.label;
|
|
6558
|
+
const fallback = this.options.find((option) => option.kind === "action");
|
|
6559
|
+
return fallback && fallback.kind === "action" ? fallback.label : "Add repositories...";
|
|
6536
6560
|
}
|
|
6537
6561
|
const selectedValues = Array.isArray(this.value) ? this.value : [];
|
|
6538
6562
|
if (selectedValues.length === 0) {
|
|
@@ -7206,8 +7230,15 @@ function buildPromptOptions(repos) {
|
|
|
7206
7230
|
kind: "action",
|
|
7207
7231
|
label: "Add repositories...",
|
|
7208
7232
|
value: ADD_REPOSITORIES_VALUE,
|
|
7209
|
-
hint: "Open GitHub
|
|
7233
|
+
hint: "Open GitHub to install/update access"
|
|
7210
7234
|
},
|
|
7235
|
+
{
|
|
7236
|
+
kind: "action",
|
|
7237
|
+
label: "Refresh list",
|
|
7238
|
+
value: REFRESH_LIST_VALUE,
|
|
7239
|
+
hint: "Re-check Dosu for new repos"
|
|
7240
|
+
},
|
|
7241
|
+
{ kind: "separator" },
|
|
7211
7242
|
...repos.map((r) => ({ kind: "repo", label: r.slug, value: r.slug }))
|
|
7212
7243
|
];
|
|
7213
7244
|
}
|
|
@@ -7218,20 +7249,23 @@ function hasNewVisibleRepository(previousRepos, nextRepos) {
|
|
|
7218
7249
|
function sleep2(ms) {
|
|
7219
7250
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
7220
7251
|
}
|
|
7221
|
-
async function waitForRepositoryRefresh(trpc, orgID, previousRepos) {
|
|
7252
|
+
async function waitForRepositoryRefresh(trpc, orgID, previousRepos, opts) {
|
|
7253
|
+
const timeoutMs = opts?.timeoutMs ?? REPO_REFRESH_POLL_TIMEOUT_MS;
|
|
7254
|
+
const intervalMs = opts?.intervalMs ?? REPO_REFRESH_POLL_INTERVAL_MS;
|
|
7222
7255
|
const startedAt = Date.now();
|
|
7223
7256
|
let latestRepos = previousRepos;
|
|
7224
|
-
while (Date.now() - startedAt <
|
|
7257
|
+
while (Date.now() - startedAt < timeoutMs) {
|
|
7225
7258
|
const polledRepos = await fetchListForOrg(trpc, orgID);
|
|
7226
7259
|
latestRepos = polledRepos.length === 0 && previousRepos.length > 0 ? previousRepos : polledRepos;
|
|
7227
7260
|
if (hasNewVisibleRepository(previousRepos, latestRepos)) {
|
|
7228
|
-
return latestRepos;
|
|
7261
|
+
return { repos: latestRepos, foundNew: true };
|
|
7229
7262
|
}
|
|
7230
|
-
await sleep2(
|
|
7263
|
+
await sleep2(intervalMs);
|
|
7231
7264
|
}
|
|
7232
|
-
return latestRepos;
|
|
7265
|
+
return { repos: latestRepos, foundNew: false };
|
|
7233
7266
|
}
|
|
7234
|
-
async function openGitHubInstallFlow(onInstalled) {
|
|
7267
|
+
async function openGitHubInstallFlow(onInstalled, opts) {
|
|
7268
|
+
const timeoutMs = opts?.timeoutMs ?? INSTALLATION_TIMEOUT_MS;
|
|
7235
7269
|
const { server, installationPromise } = await startInstallationCallbackServer();
|
|
7236
7270
|
let timeoutId;
|
|
7237
7271
|
try {
|
|
@@ -7251,9 +7285,9 @@ async function openGitHubInstallFlow(onInstalled) {
|
|
|
7251
7285
|
}
|
|
7252
7286
|
const timeout = new Promise((resolve) => {
|
|
7253
7287
|
timeoutId = setTimeout(() => {
|
|
7254
|
-
logger.warn("setup", `GitHub install timed out after ${
|
|
7288
|
+
logger.warn("setup", `GitHub install timed out after ${timeoutMs / 1000}s`);
|
|
7255
7289
|
resolve(null);
|
|
7256
|
-
},
|
|
7290
|
+
}, timeoutMs);
|
|
7257
7291
|
});
|
|
7258
7292
|
const s = Y2();
|
|
7259
7293
|
s.start("Waiting for GitHub install to complete...");
|
|
@@ -7263,7 +7297,7 @@ async function openGitHubInstallFlow(onInstalled) {
|
|
|
7263
7297
|
]);
|
|
7264
7298
|
if (result === null) {
|
|
7265
7299
|
s.stop("Timed out");
|
|
7266
|
-
M2.warn(`Didn't hear back from the browser after ${Math.floor(
|
|
7300
|
+
M2.warn(`Didn't hear back from the browser after ${Math.floor(timeoutMs / 1000)}s. Run \`dosu setup\` again once you've completed the install.`);
|
|
7267
7301
|
return null;
|
|
7268
7302
|
}
|
|
7269
7303
|
if (onInstalled) {
|
|
@@ -7399,14 +7433,26 @@ ${lines}`);
|
|
|
7399
7433
|
return { advance: false, has_connected_repo: deployed.length > 0 };
|
|
7400
7434
|
}
|
|
7401
7435
|
if (selected === ADD_REPOSITORIES_VALUE) {
|
|
7402
|
-
let
|
|
7436
|
+
let refresh = { repos, foundNew: false };
|
|
7403
7437
|
const installationID = await openGitHubInstallFlow(async () => {
|
|
7404
|
-
|
|
7405
|
-
});
|
|
7438
|
+
refresh = await waitForRepositoryRefresh(trpc, orgID, repos, opts.refresh);
|
|
7439
|
+
}, opts.install);
|
|
7406
7440
|
if (installationID === null) {
|
|
7407
7441
|
return { advance: false, has_connected_repo: deployed.length > 0 };
|
|
7408
7442
|
}
|
|
7409
|
-
repos =
|
|
7443
|
+
repos = refresh.repos;
|
|
7444
|
+
if (!refresh.foundNew) {
|
|
7445
|
+
M2.warn("GitHub may still be syncing. Pick 'Refresh list' in a moment to re-check — sync usually completes within a minute.");
|
|
7446
|
+
}
|
|
7447
|
+
continue;
|
|
7448
|
+
}
|
|
7449
|
+
if (selected === REFRESH_LIST_VALUE) {
|
|
7450
|
+
const s2 = Y2();
|
|
7451
|
+
s2.start("Refreshing repository list...");
|
|
7452
|
+
const previousIds = new Set(repos.map((r) => r.repository_id));
|
|
7453
|
+
repos = await fetchListForOrg(trpc, orgID);
|
|
7454
|
+
const newCount = repos.filter((r) => !previousIds.has(r.repository_id)).length;
|
|
7455
|
+
s2.stop(newCount > 0 ? `Found ${newCount} new repo${newCount === 1 ? "" : "s"}` : "List refreshed — no new repos yet");
|
|
7410
7456
|
continue;
|
|
7411
7457
|
}
|
|
7412
7458
|
const slugs = selected;
|
|
@@ -8349,6 +8395,8 @@ __export(exports_flow2, {
|
|
|
8349
8395
|
runInstallSkill: () => runInstallSkill,
|
|
8350
8396
|
isStdioOnly: () => isStdioOnly
|
|
8351
8397
|
});
|
|
8398
|
+
import { existsSync as existsSync9 } from "node:fs";
|
|
8399
|
+
import { join as join19 } from "node:path";
|
|
8352
8400
|
async function runSetup(opts = {}) {
|
|
8353
8401
|
logger.info("setup", `Setup flow started${opts.deploymentID ? ` deployment=${opts.deploymentID}` : ""}${opts.mode ? ` mode=${opts.mode}` : ""}`);
|
|
8354
8402
|
Ie("Dosu CLI Setup");
|
|
@@ -8439,7 +8487,11 @@ async function runSetup(opts = {}) {
|
|
|
8439
8487
|
}
|
|
8440
8488
|
}
|
|
8441
8489
|
if (mcpConfiguredThisRun) {
|
|
8442
|
-
showTryItOutPrompt(
|
|
8490
|
+
showTryItOutPrompt({
|
|
8491
|
+
mode: cfg.mode,
|
|
8492
|
+
docsImported: choices.connectGitHub && githubOnboardingDone,
|
|
8493
|
+
hasAgentsMd: existsSync9(join19(process.cwd(), "AGENTS.md"))
|
|
8494
|
+
});
|
|
8443
8495
|
}
|
|
8444
8496
|
if (cfg.mode === MODE_OSS) {
|
|
8445
8497
|
Se("Setup complete! Using open-source libraries only.\n\nTips: Run `dosu setup --mode cloud` to connect your own repos.");
|
|
@@ -8799,12 +8851,12 @@ async function stepSelectTools(detected) {
|
|
|
8799
8851
|
return {
|
|
8800
8852
|
label: p2.name(),
|
|
8801
8853
|
value: p2.id(),
|
|
8802
|
-
hint: configured ? "configured" : undefined
|
|
8854
|
+
hint: configured ? "configured — untick to remove" : undefined
|
|
8803
8855
|
};
|
|
8804
8856
|
});
|
|
8805
8857
|
const preselected = detected.filter((p2) => configuredMap.get(p2.id())).map((p2) => p2.id());
|
|
8806
8858
|
const selected = await fe({
|
|
8807
|
-
message: "Select agents to configure
|
|
8859
|
+
message: "Select agents — tick to configure, untick to remove",
|
|
8808
8860
|
options,
|
|
8809
8861
|
initialValues: preselected
|
|
8810
8862
|
});
|
|
@@ -8875,8 +8927,19 @@ ${lines}`);
|
|
|
8875
8927
|
M2.success("All agents already configured. No changes needed.");
|
|
8876
8928
|
}
|
|
8877
8929
|
}
|
|
8878
|
-
function showTryItOutPrompt(
|
|
8879
|
-
const prompt =
|
|
8930
|
+
function showTryItOutPrompt(opts = {}) {
|
|
8931
|
+
const prompt = (() => {
|
|
8932
|
+
if (opts.mode === MODE_OSS) {
|
|
8933
|
+
return `What can Dosu help me with? Pick an open source library related to my project and explain how it works.`;
|
|
8934
|
+
}
|
|
8935
|
+
if (opts.docsImported) {
|
|
8936
|
+
return `Use Dosu to summarize the most important docs in my repo.`;
|
|
8937
|
+
}
|
|
8938
|
+
if (opts.hasAgentsMd) {
|
|
8939
|
+
return `Please use Dosu to host my AGENTS.md`;
|
|
8940
|
+
}
|
|
8941
|
+
return `Ask Dosu to draft an AGENTS.md for this project.`;
|
|
8942
|
+
})();
|
|
8880
8943
|
M2.message(`Try it out! Paste this into your agent:
|
|
8881
8944
|
|
|
8882
8945
|
${info(prompt)}`);
|