@dosu/cli 0.11.0-alpha.4 → 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.
Files changed (2) hide show
  1. package/bin/dosu.js +164 -116
  2. 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.4";
4344
+ var VERSION = "0.11.0-alpha.6";
4345
4345
 
4346
4346
  // src/debug/logger.ts
4347
4347
  import {
@@ -4744,10 +4744,11 @@ function checkForSkillUpdates() {
4744
4744
  const isStale = !cache || Date.now() - cache.lastCheck > CHECK_INTERVAL_MS;
4745
4745
  if (isStale) {
4746
4746
  fetchLatestSha().then((latest) => {
4747
+ const fresh = readSkillCache();
4747
4748
  writeSkillCache({
4748
4749
  lastCheck: Date.now(),
4749
- latestSha: latest ?? cache?.latestSha ?? "",
4750
- installedSha: cache?.installedSha ?? ""
4750
+ latestSha: latest ?? fresh?.latestSha ?? "",
4751
+ installedSha: fresh?.installedSha ?? ""
4751
4752
  });
4752
4753
  if (latest) {
4753
4754
  logger.debug("skill-update-check", `Cached latest SHA: ${latest}`);
@@ -6378,6 +6379,28 @@ var init_default_deployment_config = __esm(() => {
6378
6379
  };
6379
6380
  });
6380
6381
 
6382
+ // src/setup/prompt-symbols.ts
6383
+ function symbol(unicodeValue, asciiValue) {
6384
+ return unicode ? unicodeValue : asciiValue;
6385
+ }
6386
+ function supportsUnicode() {
6387
+ if (process.platform !== "win32") {
6388
+ return process.env.TERM !== "linux";
6389
+ }
6390
+ return !!(process.env.CI || process.env.WT_SESSION || process.env.TERMINUS_SUBLIME || process.env.ConEmuTask === "{cmd::Cmder}" || process.env.TERM_PROGRAM === "Terminus-Sublime" || process.env.TERM_PROGRAM === "vscode" || process.env.TERM === "xterm-256color" || process.env.TERM === "alacritty" || process.env.TERMINAL_EMULATOR === "JetBrains-JediTerm");
6391
+ }
6392
+ var unicode, ACTIVE_SYMBOL, SUBMIT_SYMBOL, CANCEL_SYMBOL, BAR, FOOTER, CHECKBOX_OFF, CHECKBOX_ON, ELLIPSIS = "...";
6393
+ var init_prompt_symbols = __esm(() => {
6394
+ unicode = supportsUnicode();
6395
+ ACTIVE_SYMBOL = symbol("◆", "*");
6396
+ SUBMIT_SYMBOL = symbol("◇", "o");
6397
+ CANCEL_SYMBOL = symbol("■", "x");
6398
+ BAR = symbol("│", "|");
6399
+ FOOTER = symbol("└", "-");
6400
+ CHECKBOX_OFF = symbol("◻", "[ ]");
6401
+ CHECKBOX_ON = symbol("◼", "[+]");
6402
+ });
6403
+
6381
6404
  // src/setup/github-repo-prompt.ts
6382
6405
  async function promptGitHubRepositories({
6383
6406
  message,
@@ -6416,28 +6439,13 @@ function visibleOptions(cursor, options, maxItems) {
6416
6439
  return { kind: "option", index: start + index };
6417
6440
  });
6418
6441
  }
6419
- function supportsUnicode() {
6420
- if (process.platform !== "win32") {
6421
- return process.env.TERM !== "linux";
6422
- }
6423
- return !!(process.env.CI || process.env.WT_SESSION || process.env.TERMINUS_SUBLIME || process.env.ConEmuTask === "{cmd::Cmder}" || process.env.TERM_PROGRAM === "Terminus-Sublime" || process.env.TERM_PROGRAM === "vscode" || process.env.TERM === "xterm-256color" || process.env.TERM === "alacritty" || process.env.TERMINAL_EMULATOR === "JetBrains-JediTerm");
6424
- }
6425
- function symbol(unicodeValue, asciiValue) {
6426
- return unicode ? unicodeValue : asciiValue;
6427
- }
6428
- var import_picocolors22, unicode, ACTIVE_SYMBOL, SUBMIT_SYMBOL, CANCEL_SYMBOL, BAR, FOOTER, CHECKBOX_OFF, CHECKBOX_ON, ACTION_ARROW, ELLIPSIS = "...", 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;
6429
6443
  var init_github_repo_prompt = __esm(() => {
6430
6444
  init_dist5();
6445
+ init_prompt_symbols();
6431
6446
  import_picocolors22 = __toESM(require_picocolors(), 1);
6432
- unicode = supportsUnicode();
6433
- ACTIVE_SYMBOL = symbol("◆", "*");
6434
- SUBMIT_SYMBOL = symbol("◇", "o");
6435
- CANCEL_SYMBOL = symbol("■", "x");
6436
- BAR = symbol("│", "|");
6437
- FOOTER = symbol("└", "-");
6438
- CHECKBOX_OFF = symbol("◻", "[ ]");
6439
- CHECKBOX_ON = symbol("◼", "[+]");
6440
6447
  ACTION_ARROW = symbol("→", ">");
6448
+ SEPARATOR_LINE = "─".repeat(30);
6441
6449
  GitHubRepoPrompt = class GitHubRepoPrompt extends x {
6442
6450
  options;
6443
6451
  message;
@@ -6454,7 +6462,8 @@ var init_github_repo_prompt = __esm(() => {
6454
6462
  this.options = options;
6455
6463
  this.maxItems = maxItems;
6456
6464
  this.selected = initialValues.filter((value) => options.some((option) => option.kind === "repo" && option.value === value));
6457
- this.cursor = Math.max(this.options.findIndex((option) => option.kind === "repo" && this.selected.includes(option.value)), 0);
6465
+ const initialCursor = this.options.findIndex((option) => option.kind === "repo" && this.selected.includes(option.value));
6466
+ this.cursor = initialCursor >= 0 ? initialCursor : this.firstFocusableIndex();
6458
6467
  this.syncValue();
6459
6468
  this.on("key", (key) => {
6460
6469
  if (key === "a") {
@@ -6466,11 +6475,11 @@ var init_github_repo_prompt = __esm(() => {
6466
6475
  switch (key) {
6467
6476
  case "left":
6468
6477
  case "up":
6469
- this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
6478
+ this.cursor = this.advanceCursor(-1);
6470
6479
  break;
6471
6480
  case "down":
6472
6481
  case "right":
6473
- this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
6482
+ this.cursor = this.advanceCursor(1);
6474
6483
  break;
6475
6484
  case "space":
6476
6485
  this.toggleCurrent();
@@ -6479,6 +6488,22 @@ var init_github_repo_prompt = __esm(() => {
6479
6488
  this.syncValue();
6480
6489
  });
6481
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
+ }
6482
6507
  get currentOption() {
6483
6508
  return this.options[this.cursor] ?? this.options[0];
6484
6509
  }
@@ -6486,10 +6511,11 @@ var init_github_repo_prompt = __esm(() => {
6486
6511
  this.value = this.currentOption.kind === "action" ? this.currentOption.value : [...this.selected];
6487
6512
  }
6488
6513
  toggleCurrent() {
6489
- if (this.currentOption.kind !== "repo")
6514
+ const current = this.currentOption;
6515
+ if (current.kind !== "repo")
6490
6516
  return;
6491
- const selected = this.selected.includes(this.currentOption.value);
6492
- this.selected = selected ? this.selected.filter((value) => value !== this.currentOption.value) : [...this.selected, this.currentOption.value];
6517
+ const selected = this.selected.includes(current.value);
6518
+ this.selected = selected ? this.selected.filter((value) => value !== current.value) : [...this.selected, current.value];
6493
6519
  }
6494
6520
  toggleAll() {
6495
6521
  const repoValues = this.options.filter((option) => option.kind === "repo").map((option) => option.value);
@@ -6507,12 +6533,14 @@ ${symbolByState} ${this.message}
6507
6533
  return `${header}${import_picocolors22.default.gray(BAR)}`;
6508
6534
  }
6509
6535
  const body = visibleOptions(this.cursor, this.options, this.maxItems).map((option) => {
6510
- const actualIndex = option.kind === "ellipsis" ? -1 : option.index;
6511
6536
  if (option.kind === "ellipsis") {
6512
6537
  return `${import_picocolors22.default.gray(BAR)} ${import_picocolors22.default.dim(ELLIPSIS)}`;
6513
6538
  }
6514
- const isActive = actualIndex === this.cursor;
6515
- const current = this.options[actualIndex];
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;
6516
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;
6517
6545
  const label = isActive ? import_picocolors22.default.cyan(current.label) : current.label;
6518
6546
  const hint = current.hint ? ` ${import_picocolors22.default.dim(`(${current.hint})`)}` : "";
@@ -6523,9 +6551,12 @@ ${symbolByState} ${this.message}
6523
6551
  ${import_picocolors22.default.cyan(FOOTER)}`;
6524
6552
  }
6525
6553
  submitLabel() {
6526
- if (this.value === ADD_REPOSITORIES_VALUE) {
6527
- const action = this.options.find((option) => option.kind === "action");
6528
- return action?.label ?? "Add repositories...";
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...";
6529
6560
  }
6530
6561
  const selectedValues = Array.isArray(this.value) ? this.value : [];
6531
6562
  if (selectedValues.length === 0) {
@@ -7199,8 +7230,15 @@ function buildPromptOptions(repos) {
7199
7230
  kind: "action",
7200
7231
  label: "Add repositories...",
7201
7232
  value: ADD_REPOSITORIES_VALUE,
7202
- hint: "Open GitHub and refresh this list"
7233
+ hint: "Open GitHub to install/update access"
7234
+ },
7235
+ {
7236
+ kind: "action",
7237
+ label: "Refresh list",
7238
+ value: REFRESH_LIST_VALUE,
7239
+ hint: "Re-check Dosu for new repos"
7203
7240
  },
7241
+ { kind: "separator" },
7204
7242
  ...repos.map((r) => ({ kind: "repo", label: r.slug, value: r.slug }))
7205
7243
  ];
7206
7244
  }
@@ -7211,20 +7249,23 @@ function hasNewVisibleRepository(previousRepos, nextRepos) {
7211
7249
  function sleep2(ms) {
7212
7250
  return new Promise((resolve) => setTimeout(resolve, ms));
7213
7251
  }
7214
- 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;
7215
7255
  const startedAt = Date.now();
7216
7256
  let latestRepos = previousRepos;
7217
- while (Date.now() - startedAt < REPO_REFRESH_POLL_TIMEOUT_MS) {
7257
+ while (Date.now() - startedAt < timeoutMs) {
7218
7258
  const polledRepos = await fetchListForOrg(trpc, orgID);
7219
7259
  latestRepos = polledRepos.length === 0 && previousRepos.length > 0 ? previousRepos : polledRepos;
7220
7260
  if (hasNewVisibleRepository(previousRepos, latestRepos)) {
7221
- return latestRepos;
7261
+ return { repos: latestRepos, foundNew: true };
7222
7262
  }
7223
- await sleep2(REPO_REFRESH_POLL_INTERVAL_MS);
7263
+ await sleep2(intervalMs);
7224
7264
  }
7225
- return latestRepos;
7265
+ return { repos: latestRepos, foundNew: false };
7226
7266
  }
7227
- async function openGitHubInstallFlow(onInstalled) {
7267
+ async function openGitHubInstallFlow(onInstalled, opts) {
7268
+ const timeoutMs = opts?.timeoutMs ?? INSTALLATION_TIMEOUT_MS;
7228
7269
  const { server, installationPromise } = await startInstallationCallbackServer();
7229
7270
  let timeoutId;
7230
7271
  try {
@@ -7244,9 +7285,9 @@ async function openGitHubInstallFlow(onInstalled) {
7244
7285
  }
7245
7286
  const timeout = new Promise((resolve) => {
7246
7287
  timeoutId = setTimeout(() => {
7247
- logger.warn("setup", `GitHub install timed out after ${INSTALLATION_TIMEOUT_MS / 1000}s`);
7288
+ logger.warn("setup", `GitHub install timed out after ${timeoutMs / 1000}s`);
7248
7289
  resolve(null);
7249
- }, INSTALLATION_TIMEOUT_MS);
7290
+ }, timeoutMs);
7250
7291
  });
7251
7292
  const s = Y2();
7252
7293
  s.start("Waiting for GitHub install to complete...");
@@ -7256,7 +7297,7 @@ async function openGitHubInstallFlow(onInstalled) {
7256
7297
  ]);
7257
7298
  if (result === null) {
7258
7299
  s.stop("Timed out");
7259
- M2.warn(`Didn't hear back from the browser after ${Math.floor(INSTALLATION_TIMEOUT_MS / 1000)}s. Run \`dosu setup\` again once you've completed the install.`);
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.`);
7260
7301
  return null;
7261
7302
  }
7262
7303
  if (onInstalled) {
@@ -7298,7 +7339,8 @@ async function createDeploymentForRepo(trpc, orgID, spaceID, repo) {
7298
7339
  });
7299
7340
  if (!dataSource?.data_source_id) {
7300
7341
  logger.warn("setup", `dataSource.create returned no data_source for ${repo.slug}`);
7301
- return { deployment_id: deployment.deployment_id };
7342
+ await deleteOrphanDeployment(trpc, deployment.deployment_id, repo.slug);
7343
+ return null;
7302
7344
  }
7303
7345
  await trpc.dataSource.syncDataSource.mutate(dataSource.data_source_id);
7304
7346
  const spaceDeployments = await trpc.workspaces.listForSpace.query(spaceID);
@@ -7391,14 +7433,26 @@ ${lines}`);
7391
7433
  return { advance: false, has_connected_repo: deployed.length > 0 };
7392
7434
  }
7393
7435
  if (selected === ADD_REPOSITORIES_VALUE) {
7394
- let refreshedRepos = repos;
7436
+ let refresh = { repos, foundNew: false };
7395
7437
  const installationID = await openGitHubInstallFlow(async () => {
7396
- refreshedRepos = await waitForRepositoryRefresh(trpc, orgID, repos);
7397
- });
7438
+ refresh = await waitForRepositoryRefresh(trpc, orgID, repos, opts.refresh);
7439
+ }, opts.install);
7398
7440
  if (installationID === null) {
7399
7441
  return { advance: false, has_connected_repo: deployed.length > 0 };
7400
7442
  }
7401
- repos = refreshedRepos;
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");
7402
7456
  continue;
7403
7457
  }
7404
7458
  const slugs = selected;
@@ -7422,17 +7476,17 @@ ${lines}`);
7422
7476
  });
7423
7477
  }
7424
7478
  }
7425
- const expectedDsIds = created.map((c) => c.data_source_id).filter((id) => Boolean(id));
7479
+ const expectedDsIds = created.map((c) => c.data_source_id);
7426
7480
  const survivors = await verifyDataSourcesPersist(trpc, orgID, expectedDsIds, opts.verify);
7427
7481
  const reverted = [];
7428
7482
  if (survivors.dropped.size > 0) {
7429
- const droppedEntries = created.filter((c) => c.data_source_id && survivors.dropped.has(c.data_source_id));
7483
+ const droppedEntries = created.filter((c) => survivors.dropped.has(c.data_source_id));
7430
7484
  for (const entry of droppedEntries) {
7431
7485
  await deleteOrphanDeployment(trpc, entry.deployment_id, entry.slug);
7432
7486
  reverted.push({ slug: entry.slug, deployment_id: entry.deployment_id });
7433
7487
  }
7434
7488
  }
7435
- const survived = created.filter((c) => !c.data_source_id || survivors.alive.has(c.data_source_id));
7489
+ const survived = created.filter((c) => survivors.alive.has(c.data_source_id));
7436
7490
  if (survived.length === 0) {
7437
7491
  s.stop("Failed");
7438
7492
  if (reverted.length > 0) {
@@ -7453,13 +7507,12 @@ ${lines}`);
7453
7507
  ${dim(`deployment ${deployment_id}`)}`);
7454
7508
  }
7455
7509
  const primary = (detected && survived.find((c) => c.slug === detected.slug)) ?? survived[0];
7456
- const survivingDataSourceIds = survived.map((c) => c.data_source_id).filter((id) => Boolean(id));
7457
7510
  return {
7458
7511
  advance: true,
7459
7512
  has_connected_repo: true,
7460
7513
  deployment_id: primary.deployment_id,
7461
7514
  space_id: cfg.space_id,
7462
- created_data_source_ids: survivingDataSourceIds
7515
+ created_data_source_ids: survived.map((c) => c.data_source_id)
7463
7516
  };
7464
7517
  }
7465
7518
  }
@@ -7520,28 +7573,12 @@ function wrapIndex(index, length) {
7520
7573
  function isPrintableKey(key) {
7521
7574
  return key.length === 1 && key >= " " && key !== "";
7522
7575
  }
7523
- function supportsUnicode2() {
7524
- if (process.platform !== "win32") {
7525
- return process.env.TERM !== "linux";
7526
- }
7527
- return !!(process.env.CI || process.env.WT_SESSION || process.env.TERMINUS_SUBLIME || process.env.ConEmuTask === "{cmd::Cmder}" || process.env.TERM_PROGRAM === "Terminus-Sublime" || process.env.TERM_PROGRAM === "vscode" || process.env.TERM === "xterm-256color" || process.env.TERM === "alacritty" || process.env.TERMINAL_EMULATOR === "JetBrains-JediTerm");
7528
- }
7529
- function symbol2(unicodeValue, asciiValue) {
7530
- return unicode2 ? unicodeValue : asciiValue;
7531
- }
7532
- var import_picocolors23, unicode2, ACTIVE_SYMBOL2, SUBMIT_SYMBOL2, CANCEL_SYMBOL2, BAR2, FOOTER2, CHECKBOX_OFF2, CHECKBOX_ON2, CHECKBOX_PARTIAL, ELLIPSIS2 = "...", MAX_VISIBLE_FILE_ITEMS = 15, GitHubDocsImportPrompt;
7576
+ var import_picocolors23, CHECKBOX_PARTIAL, MAX_VISIBLE_FILE_ITEMS = 15, GitHubDocsImportPrompt;
7533
7577
  var init_github_doc_import_prompt = __esm(() => {
7534
7578
  init_dist5();
7579
+ init_prompt_symbols();
7535
7580
  import_picocolors23 = __toESM(require_picocolors(), 1);
7536
- unicode2 = supportsUnicode2();
7537
- ACTIVE_SYMBOL2 = symbol2("◆", "*");
7538
- SUBMIT_SYMBOL2 = symbol2("◇", "o");
7539
- CANCEL_SYMBOL2 = symbol2("■", "x");
7540
- BAR2 = symbol2("│", "|");
7541
- FOOTER2 = symbol2("└", "-");
7542
- CHECKBOX_OFF2 = symbol2("◻", "[ ]");
7543
- CHECKBOX_ON2 = symbol2("◼", "[+]");
7544
- CHECKBOX_PARTIAL = symbol2("◧", "[-]");
7581
+ CHECKBOX_PARTIAL = symbol("◧", "[-]");
7545
7582
  GitHubDocsImportPrompt = class GitHubDocsImportPrompt extends x {
7546
7583
  repositories;
7547
7584
  mode = "repos";
@@ -7757,24 +7794,24 @@ var init_github_doc_import_prompt = __esm(() => {
7757
7794
  return "partial";
7758
7795
  }
7759
7796
  renderPrompt() {
7760
- const promptSymbol = this.state === "submit" ? import_picocolors23.default.green(SUBMIT_SYMBOL2) : this.state === "cancel" ? import_picocolors23.default.red(CANCEL_SYMBOL2) : import_picocolors23.default.cyan(ACTIVE_SYMBOL2);
7797
+ const promptSymbol = this.state === "submit" ? import_picocolors23.default.green(SUBMIT_SYMBOL) : this.state === "cancel" ? import_picocolors23.default.red(CANCEL_SYMBOL) : import_picocolors23.default.cyan(ACTIVE_SYMBOL);
7761
7798
  const title = this.mode === "repos" ? "Select docs to import" : this.currentRepository?.slug ?? "Files";
7762
- const header = `${import_picocolors23.default.gray(BAR2)}
7799
+ const header = `${import_picocolors23.default.gray(BAR)}
7763
7800
  ${promptSymbol} ${title}
7764
7801
  `;
7765
7802
  if (this.state === "submit") {
7766
- return `${header}${import_picocolors23.default.gray(BAR2)} ${import_picocolors23.default.dim(this.submitLabel())}`;
7803
+ return `${header}${import_picocolors23.default.gray(BAR)} ${import_picocolors23.default.dim(this.submitLabel())}`;
7767
7804
  }
7768
7805
  if (this.state === "cancel") {
7769
- return `${header}${import_picocolors23.default.gray(BAR2)}`;
7806
+ return `${header}${import_picocolors23.default.gray(BAR)}`;
7770
7807
  }
7771
7808
  return this.mode === "repos" ? this.renderRepositoryMode(header) : this.renderFileMode(header);
7772
7809
  }
7773
7810
  renderRepositoryMode(header) {
7774
- const help = `${import_picocolors23.default.gray(BAR2)} ${import_picocolors23.default.dim("space: import all docs in a repo →: browse repo docs Enter: confirm")}`;
7811
+ const help = `${import_picocolors23.default.gray(BAR)} ${import_picocolors23.default.dim("space: import all docs in a repo →: browse repo docs Enter: confirm")}`;
7775
7812
  const body = visibleOptions2(this.repoCursor, this.repositories.length).map((option) => {
7776
7813
  if (option.kind === "ellipsis") {
7777
- return `${import_picocolors23.default.gray(BAR2)} ${import_picocolors23.default.dim(ELLIPSIS2)}`;
7814
+ return `${import_picocolors23.default.gray(BAR)} ${import_picocolors23.default.dim(ELLIPSIS)}`;
7778
7815
  }
7779
7816
  const repo = this.repositories[option.index];
7780
7817
  const isActive = option.index === this.repoCursor;
@@ -7782,53 +7819,53 @@ ${promptSymbol} ${title}
7782
7819
  const marker = this.renderRepositoryMarker(state, isActive);
7783
7820
  const label = isActive ? import_picocolors23.default.cyan(repo.slug) : repo.slug;
7784
7821
  const hint = state === "locked" ? ` ${import_picocolors23.default.dim("(All docs already imported)")}` : "";
7785
- return `${import_picocolors23.default.gray(BAR2)} ${marker} ${label}${hint}`;
7822
+ return `${import_picocolors23.default.gray(BAR)} ${marker} ${label}${hint}`;
7786
7823
  });
7787
7824
  return `${header}${help}
7788
- ${import_picocolors23.default.gray(BAR2)}
7825
+ ${import_picocolors23.default.gray(BAR)}
7789
7826
  ${body.join(`
7790
7827
  `)}
7791
- ${import_picocolors23.default.cyan(FOOTER2)}`;
7828
+ ${import_picocolors23.default.cyan(FOOTER)}`;
7792
7829
  }
7793
7830
  renderFileMode(header) {
7794
- const back = `${import_picocolors23.default.gray(BAR2)} ${import_picocolors23.default.dim("←: back / Enter")}`;
7831
+ const back = `${import_picocolors23.default.gray(BAR)} ${import_picocolors23.default.dim("←: back / Enter")}`;
7795
7832
  const searchValue = this.searchQuery || import_picocolors23.default.dim(this.searchActive ? "" : "type to filter");
7796
- const search = `${import_picocolors23.default.gray(BAR2)} Search: ${searchValue}`;
7797
- const help = `${import_picocolors23.default.gray(BAR2)} ${import_picocolors23.default.dim("space: toggle doc type: search a: select all visible ←: back / Enter")}`;
7833
+ const search = `${import_picocolors23.default.gray(BAR)} Search: ${searchValue}`;
7834
+ const help = `${import_picocolors23.default.gray(BAR)} ${import_picocolors23.default.dim("space: toggle doc type: search a: select all visible ←: back / Enter")}`;
7798
7835
  const body = visibleOptions2(this.fileCursor, this.filteredFiles.length, MAX_VISIBLE_FILE_ITEMS).map((option) => {
7799
7836
  if (option.kind === "ellipsis") {
7800
- return `${import_picocolors23.default.gray(BAR2)} ${import_picocolors23.default.dim(ELLIPSIS2)}`;
7837
+ return `${import_picocolors23.default.gray(BAR)} ${import_picocolors23.default.dim(ELLIPSIS)}`;
7801
7838
  }
7802
7839
  const file = this.filteredFiles[option.index];
7803
7840
  const isActive = option.index === this.fileCursor;
7804
7841
  const isSelected = this.selectedIds.has(file.id);
7805
- const marker = file.is_synced ? isActive ? import_picocolors23.default.cyan(CHECKBOX_OFF2) : import_picocolors23.default.dim(CHECKBOX_OFF2) : isSelected ? isActive ? import_picocolors23.default.cyan(CHECKBOX_ON2) : CHECKBOX_ON2 : isActive ? import_picocolors23.default.cyan(CHECKBOX_OFF2) : CHECKBOX_OFF2;
7842
+ const marker = file.is_synced ? isActive ? import_picocolors23.default.cyan(CHECKBOX_OFF) : import_picocolors23.default.dim(CHECKBOX_OFF) : isSelected ? isActive ? import_picocolors23.default.cyan(CHECKBOX_ON) : CHECKBOX_ON : isActive ? import_picocolors23.default.cyan(CHECKBOX_OFF) : CHECKBOX_OFF;
7806
7843
  const label = file.is_synced ? isActive ? import_picocolors23.default.cyan(file.path) : import_picocolors23.default.dim(file.path) : isActive ? import_picocolors23.default.cyan(file.path) : file.path;
7807
7844
  const hint = file.is_synced ? ` ${import_picocolors23.default.dim("(Already imported)")}` : "";
7808
- return `${import_picocolors23.default.gray(BAR2)} ${marker} ${label}${hint}`;
7845
+ return `${import_picocolors23.default.gray(BAR)} ${marker} ${label}${hint}`;
7809
7846
  });
7810
7847
  const content = body.length > 0 ? body.join(`
7811
- `) : `${import_picocolors23.default.gray(BAR2)} ${import_picocolors23.default.dim("No docs match your search.")}`;
7848
+ `) : `${import_picocolors23.default.gray(BAR)} ${import_picocolors23.default.dim("No docs match your search.")}`;
7812
7849
  return `${header}${back}
7813
- ${import_picocolors23.default.gray(BAR2)}
7850
+ ${import_picocolors23.default.gray(BAR)}
7814
7851
  ${search}
7815
- ${import_picocolors23.default.gray(BAR2)}
7852
+ ${import_picocolors23.default.gray(BAR)}
7816
7853
  ${content}
7817
- ${import_picocolors23.default.gray(BAR2)}
7854
+ ${import_picocolors23.default.gray(BAR)}
7818
7855
  ${help}
7819
- ${import_picocolors23.default.cyan(FOOTER2)}`;
7856
+ ${import_picocolors23.default.cyan(FOOTER)}`;
7820
7857
  }
7821
7858
  renderRepositoryMarker(state, isActive) {
7822
7859
  if (state === "all") {
7823
- return isActive ? import_picocolors23.default.cyan(CHECKBOX_ON2) : CHECKBOX_ON2;
7860
+ return isActive ? import_picocolors23.default.cyan(CHECKBOX_ON) : CHECKBOX_ON;
7824
7861
  }
7825
7862
  if (state === "partial") {
7826
7863
  return isActive ? import_picocolors23.default.cyan(CHECKBOX_PARTIAL) : CHECKBOX_PARTIAL;
7827
7864
  }
7828
7865
  if (state === "locked") {
7829
- return isActive ? import_picocolors23.default.cyan(CHECKBOX_OFF2) : import_picocolors23.default.dim(CHECKBOX_OFF2);
7866
+ return isActive ? import_picocolors23.default.cyan(CHECKBOX_OFF) : import_picocolors23.default.dim(CHECKBOX_OFF);
7830
7867
  }
7831
- return isActive ? import_picocolors23.default.cyan(CHECKBOX_OFF2) : CHECKBOX_OFF2;
7868
+ return isActive ? import_picocolors23.default.cyan(CHECKBOX_OFF) : CHECKBOX_OFF;
7832
7869
  }
7833
7870
  submitLabel() {
7834
7871
  const count = this.selectedIds.size;
@@ -8358,6 +8395,8 @@ __export(exports_flow2, {
8358
8395
  runInstallSkill: () => runInstallSkill,
8359
8396
  isStdioOnly: () => isStdioOnly
8360
8397
  });
8398
+ import { existsSync as existsSync9 } from "node:fs";
8399
+ import { join as join19 } from "node:path";
8361
8400
  async function runSetup(opts = {}) {
8362
8401
  logger.info("setup", `Setup flow started${opts.deploymentID ? ` deployment=${opts.deploymentID}` : ""}${opts.mode ? ` mode=${opts.mode}` : ""}`);
8363
8402
  Ie("Dosu CLI Setup");
@@ -8448,7 +8487,11 @@ async function runSetup(opts = {}) {
8448
8487
  }
8449
8488
  }
8450
8489
  if (mcpConfiguredThisRun) {
8451
- showTryItOutPrompt(cfg.mode);
8490
+ showTryItOutPrompt({
8491
+ mode: cfg.mode,
8492
+ docsImported: choices.connectGitHub && githubOnboardingDone,
8493
+ hasAgentsMd: existsSync9(join19(process.cwd(), "AGENTS.md"))
8494
+ });
8452
8495
  }
8453
8496
  if (cfg.mode === MODE_OSS) {
8454
8497
  Se("Setup complete! Using open-source libraries only.\n\nTips: Run `dosu setup --mode cloud` to connect your own repos.");
@@ -8456,6 +8499,12 @@ async function runSetup(opts = {}) {
8456
8499
  Se("\uD83C\uDF89 Setup complete!");
8457
8500
  }
8458
8501
  }
8502
+ function applyDeployment(cfg, d3) {
8503
+ cfg.deployment_id = d3.deployment_id;
8504
+ cfg.deployment_name = d3.name;
8505
+ cfg.org_id = d3.org_id;
8506
+ cfg.space_id = d3.space_id;
8507
+ }
8459
8508
  function applyModeOverride(cfg, opts) {
8460
8509
  if (!opts.mode)
8461
8510
  return;
@@ -8637,10 +8686,7 @@ async function bindOnboardingDeployment(apiClient, cfg, targetOrg) {
8637
8686
  return false;
8638
8687
  }
8639
8688
  cfg.mode = undefined;
8640
- cfg.deployment_id = deployment.deployment_id;
8641
- cfg.deployment_name = deployment.name;
8642
- cfg.org_id = deployment.org_id;
8643
- cfg.space_id = deployment.space_id;
8689
+ applyDeployment(cfg, deployment);
8644
8690
  logger.info("setup", `Bound onboarding context org=${targetOrg.org_id} deployment=${deployment.deployment_id}`);
8645
8691
  M2.success(`Organization
8646
8692
  ${dim(targetOrg.name)}`);
@@ -8657,19 +8703,13 @@ async function resolveDeployment(apiClient, cfg, opts) {
8657
8703
  if (!d4)
8658
8704
  return false;
8659
8705
  cfg.mode = undefined;
8660
- cfg.deployment_id = d4.deployment_id;
8661
- cfg.deployment_name = d4.name;
8662
- cfg.org_id = d4.org_id;
8663
- cfg.space_id = d4.space_id;
8706
+ applyDeployment(cfg, d4);
8664
8707
  return true;
8665
8708
  }
8666
8709
  if (cfg.mode === MODE_OSS) {
8667
8710
  const deployments = await fetchDeployments(apiClient);
8668
8711
  if (deployments.length > 0) {
8669
- cfg.deployment_id = deployments[0].deployment_id;
8670
- cfg.deployment_name = deployments[0].name;
8671
- cfg.org_id = deployments[0].org_id;
8672
- cfg.space_id = deployments[0].space_id;
8712
+ applyDeployment(cfg, deployments[0]);
8673
8713
  }
8674
8714
  return true;
8675
8715
  }
@@ -8680,10 +8720,7 @@ async function resolveDeployment(apiClient, cfg, opts) {
8680
8720
  if (!d3)
8681
8721
  return false;
8682
8722
  cfg.mode = undefined;
8683
- cfg.deployment_id = d3.deployment_id;
8684
- cfg.deployment_name = d3.name;
8685
- cfg.org_id = d3.org_id;
8686
- cfg.space_id = d3.space_id;
8723
+ applyDeployment(cfg, d3);
8687
8724
  return true;
8688
8725
  }
8689
8726
  async function fetchDeployments(apiClient) {
@@ -8814,12 +8851,12 @@ async function stepSelectTools(detected) {
8814
8851
  return {
8815
8852
  label: p2.name(),
8816
8853
  value: p2.id(),
8817
- hint: configured ? "configured" : undefined
8854
+ hint: configured ? "configured — untick to remove" : undefined
8818
8855
  };
8819
8856
  });
8820
8857
  const preselected = detected.filter((p2) => configuredMap.get(p2.id())).map((p2) => p2.id());
8821
8858
  const selected = await fe({
8822
- message: "Select agents to configure or update",
8859
+ message: "Select agents — tick to configure, untick to remove",
8823
8860
  options,
8824
8861
  initialValues: preselected
8825
8862
  });
@@ -8890,8 +8927,19 @@ ${lines}`);
8890
8927
  M2.success("All agents already configured. No changes needed.");
8891
8928
  }
8892
8929
  }
8893
- function showTryItOutPrompt(mode) {
8894
- const prompt = mode === MODE_OSS ? `What can Dosu help me with? Pick an open source library related to my project and explain how it works.` : `Please use Dosu to host my AGENTS.md`;
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
+ })();
8895
8943
  M2.message(`Try it out! Paste this into your agent:
8896
8944
 
8897
8945
  ${info(prompt)}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dosu/cli",
3
- "version": "0.11.0-alpha.4",
3
+ "version": "0.11.0-alpha.6",
4
4
  "type": "module",
5
5
  "description": "Dosu CLI - Manage MCP servers for AI tools",
6
6
  "license": "MIT",