@dosu/cli 0.11.0-alpha.3 → 0.11.0-alpha.5

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 +192 -100
  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.3";
4344
+ var VERSION = "0.11.0-alpha.5";
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,27 +6439,11 @@ 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, ADD_REPOSITORIES_VALUE = "__add_repositories__", 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("→", ">");
6441
6448
  GitHubRepoPrompt = class GitHubRepoPrompt extends x {
6442
6449
  options;
@@ -7148,6 +7155,7 @@ var init_open = __esm(() => {
7148
7155
  // src/setup/github-step.ts
7149
7156
  var exports_github_step = {};
7150
7157
  __export(exports_github_step, {
7158
+ verifyDataSourcesPersist: () => verifyDataSourcesPersist,
7151
7159
  stepConnectGitHubRepo: () => stepConnectGitHubRepo,
7152
7160
  detectGitRepo: () => detectGitRepo
7153
7161
  });
@@ -7175,24 +7183,32 @@ function detectGitRepo(cwd = process.cwd()) {
7175
7183
  }
7176
7184
  async function fetchListForOrg(trpc, orgID) {
7177
7185
  try {
7178
- return await trpc.githubRepository.listForOrg.query({
7186
+ const repos = await trpc.githubRepository.listForOrg.query({
7179
7187
  org_id: orgID
7180
7188
  });
7189
+ return sortReposByRecency(repos);
7181
7190
  } catch (err) {
7182
7191
  const msg = err instanceof Error ? err.message : String(err);
7183
7192
  logger.warn("setup", `listForOrg failed: ${msg}`);
7184
7193
  return [];
7185
7194
  }
7186
7195
  }
7196
+ function sortReposByRecency(repos) {
7197
+ return [...repos].sort((a, b3) => {
7198
+ const ta = Date.parse(a.created_at ?? "") || 0;
7199
+ const tb = Date.parse(b3.created_at ?? "") || 0;
7200
+ return tb - ta;
7201
+ });
7202
+ }
7187
7203
  function buildPromptOptions(repos) {
7188
7204
  return [
7189
- ...repos.map((r) => ({ kind: "repo", label: r.slug, value: r.slug })),
7190
7205
  {
7191
7206
  kind: "action",
7192
7207
  label: "Add repositories...",
7193
7208
  value: ADD_REPOSITORIES_VALUE,
7194
7209
  hint: "Open GitHub and refresh this list"
7195
- }
7210
+ },
7211
+ ...repos.map((r) => ({ kind: "repo", label: r.slug, value: r.slug }))
7196
7212
  ];
7197
7213
  }
7198
7214
  function hasNewVisibleRepository(previousRepos, nextRepos) {
@@ -7289,7 +7305,8 @@ async function createDeploymentForRepo(trpc, orgID, spaceID, repo) {
7289
7305
  });
7290
7306
  if (!dataSource?.data_source_id) {
7291
7307
  logger.warn("setup", `dataSource.create returned no data_source for ${repo.slug}`);
7292
- return { deployment_id: deployment.deployment_id };
7308
+ await deleteOrphanDeployment(trpc, deployment.deployment_id, repo.slug);
7309
+ return null;
7293
7310
  }
7294
7311
  await trpc.dataSource.syncDataSource.mutate(dataSource.data_source_id);
7295
7312
  const spaceDeployments = await trpc.workspaces.listForSpace.query(spaceID);
@@ -7297,14 +7314,59 @@ async function createDeploymentForRepo(trpc, orgID, spaceID, repo) {
7297
7314
  deployment_id: d3.deployment_id,
7298
7315
  data_source_id: dataSource.data_source_id
7299
7316
  })));
7300
- return { deployment_id: deployment.deployment_id };
7317
+ return {
7318
+ deployment_id: deployment.deployment_id,
7319
+ data_source_id: dataSource.data_source_id
7320
+ };
7301
7321
  } catch (err) {
7302
7322
  const msg = err instanceof Error ? err.message : String(err);
7303
7323
  logger.error("setup", `Failed to wire up ${repo.slug}: ${msg}`);
7304
7324
  return null;
7305
7325
  }
7306
7326
  }
7307
- async function stepConnectGitHubRepo(cfg, detected = detectGitRepo()) {
7327
+ async function verifyDataSourcesPersist(trpc, orgID, expectedDataSourceIds, opts = {}) {
7328
+ const expected = new Set(expectedDataSourceIds);
7329
+ if (expected.size === 0) {
7330
+ return { alive: new Set, dropped: new Set };
7331
+ }
7332
+ const timeoutMs = opts.timeoutMs ?? DATA_SOURCE_VERIFY_POLL_TIMEOUT_MS;
7333
+ const intervalMs = opts.intervalMs ?? DATA_SOURCE_VERIFY_POLL_INTERVAL_MS;
7334
+ const startedAt = Date.now();
7335
+ let alive = new Set;
7336
+ let dropped = new Set;
7337
+ let firstIteration = true;
7338
+ while (firstIteration || Date.now() - startedAt < timeoutMs) {
7339
+ firstIteration = false;
7340
+ let listed = [];
7341
+ try {
7342
+ listed = await trpc.dataSource.list.query({
7343
+ org_id: orgID,
7344
+ excluded_provider_slugs: []
7345
+ });
7346
+ } catch (err) {
7347
+ const msg = err instanceof Error ? err.message : String(err);
7348
+ logger.warn("setup", `dataSource.list during verify failed: ${msg}`);
7349
+ }
7350
+ const presentNow = new Set(listed.map((d3) => d3.data_source_id).filter((id) => Boolean(id)));
7351
+ alive = new Set([...expected].filter((id) => presentNow.has(id)));
7352
+ dropped = new Set([...expected].filter((id) => !presentNow.has(id)));
7353
+ if (dropped.size > 0)
7354
+ return { alive, dropped };
7355
+ if (timeoutMs === 0)
7356
+ break;
7357
+ await sleep2(intervalMs);
7358
+ }
7359
+ return { alive, dropped };
7360
+ }
7361
+ async function deleteOrphanDeployment(trpc, deploymentID, slug) {
7362
+ try {
7363
+ await trpc.workspaces.delete.mutate(deploymentID);
7364
+ } catch (err) {
7365
+ const msg = err instanceof Error ? err.message : String(err);
7366
+ logger.warn("setup", `Failed to revert orphan deployment for ${slug}: ${msg}`);
7367
+ }
7368
+ }
7369
+ async function stepConnectGitHubRepo(cfg, detected = detectGitRepo(), opts = {}) {
7308
7370
  logger.info("setup", "Step: connect GitHub repo(s)");
7309
7371
  if (!cfg.org_id || !cfg.space_id) {
7310
7372
  M2.warn("Cannot connect GitHub: your Dosu workspace is missing org/space context. Re-run `dosu setup` from a fresh state.");
@@ -7327,9 +7389,10 @@ async function stepConnectGitHubRepo(cfg, detected = detectGitRepo()) {
7327
7389
  ${lines}`);
7328
7390
  }
7329
7391
  const selected = await promptGitHubRepositories({
7330
- message: "Select repositories to connect",
7392
+ message: `Select repositories to connect ${dim(`(${undeployed.length} available)`)}`,
7331
7393
  options: buildPromptOptions(undeployed),
7332
- initialValues: []
7394
+ initialValues: [],
7395
+ maxItems: REPO_MULTISELECT_MAX_ITEMS
7333
7396
  });
7334
7397
  if (pD(selected)) {
7335
7398
  logger.info("setup", "Repository selection cancelled");
@@ -7360,29 +7423,54 @@ ${lines}`);
7360
7423
  continue;
7361
7424
  const result = await createDeploymentForRepo(trpc, orgID, spaceID, repo);
7362
7425
  if (result) {
7363
- created.push({ deployment_id: result.deployment_id, slug });
7426
+ created.push({
7427
+ deployment_id: result.deployment_id,
7428
+ data_source_id: result.data_source_id,
7429
+ slug
7430
+ });
7364
7431
  }
7365
7432
  }
7366
- if (created.length === 0) {
7433
+ const expectedDsIds = created.map((c) => c.data_source_id);
7434
+ const survivors = await verifyDataSourcesPersist(trpc, orgID, expectedDsIds, opts.verify);
7435
+ const reverted = [];
7436
+ if (survivors.dropped.size > 0) {
7437
+ const droppedEntries = created.filter((c) => survivors.dropped.has(c.data_source_id));
7438
+ for (const entry of droppedEntries) {
7439
+ await deleteOrphanDeployment(trpc, entry.deployment_id, entry.slug);
7440
+ reverted.push({ slug: entry.slug, deployment_id: entry.deployment_id });
7441
+ }
7442
+ }
7443
+ const survived = created.filter((c) => survivors.alive.has(c.data_source_id));
7444
+ if (survived.length === 0) {
7367
7445
  s.stop("Failed");
7368
- M2.error("Could not connect any repos. Check `dosu logs --tail 50` for details.");
7446
+ if (reverted.length > 0) {
7447
+ M2.error(`Couldn't sync any repos — Dosu doesn't have GitHub access to: ${reverted.map((r) => r.slug).join(", ")}.`);
7448
+ } else {
7449
+ M2.error("Could not connect any repos. Check `dosu logs --tail 50` for details.");
7450
+ }
7369
7451
  return { advance: false, has_connected_repo: deployed.length > 0 };
7370
7452
  }
7371
- s.stop(`Connected ${created.length} repo${created.length === 1 ? "" : "s"}`);
7372
- for (const { slug, deployment_id } of created) {
7453
+ if (reverted.length > 0) {
7454
+ s.stop(`Connected ${survived.length} repo${survived.length === 1 ? "" : "s"} · ${reverted.length} skipped`);
7455
+ M2.warn(`Dosu couldn't sync ${reverted.length} repo${reverted.length === 1 ? "" : "s"} (GitHub App has no access): ${reverted.map((r) => r.slug).join(", ")}`);
7456
+ } else {
7457
+ s.stop(`Connected ${survived.length} repo${survived.length === 1 ? "" : "s"}`);
7458
+ }
7459
+ for (const { slug, deployment_id } of survived) {
7373
7460
  M2.success(`${slug}
7374
7461
  ${dim(`deployment ${deployment_id}`)}`);
7375
7462
  }
7376
- const primary = (detected && created.find((c) => c.slug === detected.slug)) ?? created[0];
7463
+ const primary = (detected && survived.find((c) => c.slug === detected.slug)) ?? survived[0];
7377
7464
  return {
7378
7465
  advance: true,
7379
7466
  has_connected_repo: true,
7380
7467
  deployment_id: primary.deployment_id,
7381
- space_id: cfg.space_id
7468
+ space_id: cfg.space_id,
7469
+ created_data_source_ids: survived.map((c) => c.data_source_id)
7382
7470
  };
7383
7471
  }
7384
7472
  }
7385
- var INSTALLATION_TIMEOUT_MS, REPO_REFRESH_POLL_INTERVAL_MS = 500, REPO_REFRESH_POLL_TIMEOUT_MS = 1e4;
7473
+ var INSTALLATION_TIMEOUT_MS, REPO_REFRESH_POLL_INTERVAL_MS = 500, REPO_REFRESH_POLL_TIMEOUT_MS = 1e4, REPO_MULTISELECT_MAX_ITEMS = 10, DATA_SOURCE_VERIFY_POLL_INTERVAL_MS = 1000, DATA_SOURCE_VERIFY_POLL_TIMEOUT_MS = 1e4;
7386
7474
  var init_github_step = __esm(() => {
7387
7475
  init_dist6();
7388
7476
  init_trpc();
@@ -7439,28 +7527,12 @@ function wrapIndex(index, length) {
7439
7527
  function isPrintableKey(key) {
7440
7528
  return key.length === 1 && key >= " " && key !== "";
7441
7529
  }
7442
- function supportsUnicode2() {
7443
- if (process.platform !== "win32") {
7444
- return process.env.TERM !== "linux";
7445
- }
7446
- 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");
7447
- }
7448
- function symbol2(unicodeValue, asciiValue) {
7449
- return unicode2 ? unicodeValue : asciiValue;
7450
- }
7451
- 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;
7530
+ var import_picocolors23, CHECKBOX_PARTIAL, MAX_VISIBLE_FILE_ITEMS = 15, GitHubDocsImportPrompt;
7452
7531
  var init_github_doc_import_prompt = __esm(() => {
7453
7532
  init_dist5();
7533
+ init_prompt_symbols();
7454
7534
  import_picocolors23 = __toESM(require_picocolors(), 1);
7455
- unicode2 = supportsUnicode2();
7456
- ACTIVE_SYMBOL2 = symbol2("◆", "*");
7457
- SUBMIT_SYMBOL2 = symbol2("◇", "o");
7458
- CANCEL_SYMBOL2 = symbol2("■", "x");
7459
- BAR2 = symbol2("│", "|");
7460
- FOOTER2 = symbol2("└", "-");
7461
- CHECKBOX_OFF2 = symbol2("◻", "[ ]");
7462
- CHECKBOX_ON2 = symbol2("◼", "[+]");
7463
- CHECKBOX_PARTIAL = symbol2("◧", "[-]");
7535
+ CHECKBOX_PARTIAL = symbol("◧", "[-]");
7464
7536
  GitHubDocsImportPrompt = class GitHubDocsImportPrompt extends x {
7465
7537
  repositories;
7466
7538
  mode = "repos";
@@ -7676,24 +7748,24 @@ var init_github_doc_import_prompt = __esm(() => {
7676
7748
  return "partial";
7677
7749
  }
7678
7750
  renderPrompt() {
7679
- 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);
7751
+ 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);
7680
7752
  const title = this.mode === "repos" ? "Select docs to import" : this.currentRepository?.slug ?? "Files";
7681
- const header = `${import_picocolors23.default.gray(BAR2)}
7753
+ const header = `${import_picocolors23.default.gray(BAR)}
7682
7754
  ${promptSymbol} ${title}
7683
7755
  `;
7684
7756
  if (this.state === "submit") {
7685
- return `${header}${import_picocolors23.default.gray(BAR2)} ${import_picocolors23.default.dim(this.submitLabel())}`;
7757
+ return `${header}${import_picocolors23.default.gray(BAR)} ${import_picocolors23.default.dim(this.submitLabel())}`;
7686
7758
  }
7687
7759
  if (this.state === "cancel") {
7688
- return `${header}${import_picocolors23.default.gray(BAR2)}`;
7760
+ return `${header}${import_picocolors23.default.gray(BAR)}`;
7689
7761
  }
7690
7762
  return this.mode === "repos" ? this.renderRepositoryMode(header) : this.renderFileMode(header);
7691
7763
  }
7692
7764
  renderRepositoryMode(header) {
7693
- const help = `${import_picocolors23.default.gray(BAR2)} ${import_picocolors23.default.dim("space: import all docs in a repo →: browse repo docs Enter: confirm")}`;
7765
+ const help = `${import_picocolors23.default.gray(BAR)} ${import_picocolors23.default.dim("space: import all docs in a repo →: browse repo docs Enter: confirm")}`;
7694
7766
  const body = visibleOptions2(this.repoCursor, this.repositories.length).map((option) => {
7695
7767
  if (option.kind === "ellipsis") {
7696
- return `${import_picocolors23.default.gray(BAR2)} ${import_picocolors23.default.dim(ELLIPSIS2)}`;
7768
+ return `${import_picocolors23.default.gray(BAR)} ${import_picocolors23.default.dim(ELLIPSIS)}`;
7697
7769
  }
7698
7770
  const repo = this.repositories[option.index];
7699
7771
  const isActive = option.index === this.repoCursor;
@@ -7701,53 +7773,53 @@ ${promptSymbol} ${title}
7701
7773
  const marker = this.renderRepositoryMarker(state, isActive);
7702
7774
  const label = isActive ? import_picocolors23.default.cyan(repo.slug) : repo.slug;
7703
7775
  const hint = state === "locked" ? ` ${import_picocolors23.default.dim("(All docs already imported)")}` : "";
7704
- return `${import_picocolors23.default.gray(BAR2)} ${marker} ${label}${hint}`;
7776
+ return `${import_picocolors23.default.gray(BAR)} ${marker} ${label}${hint}`;
7705
7777
  });
7706
7778
  return `${header}${help}
7707
- ${import_picocolors23.default.gray(BAR2)}
7779
+ ${import_picocolors23.default.gray(BAR)}
7708
7780
  ${body.join(`
7709
7781
  `)}
7710
- ${import_picocolors23.default.cyan(FOOTER2)}`;
7782
+ ${import_picocolors23.default.cyan(FOOTER)}`;
7711
7783
  }
7712
7784
  renderFileMode(header) {
7713
- const back = `${import_picocolors23.default.gray(BAR2)} ${import_picocolors23.default.dim("←: back / Enter")}`;
7785
+ const back = `${import_picocolors23.default.gray(BAR)} ${import_picocolors23.default.dim("←: back / Enter")}`;
7714
7786
  const searchValue = this.searchQuery || import_picocolors23.default.dim(this.searchActive ? "" : "type to filter");
7715
- const search = `${import_picocolors23.default.gray(BAR2)} Search: ${searchValue}`;
7716
- const help = `${import_picocolors23.default.gray(BAR2)} ${import_picocolors23.default.dim("space: toggle doc type: search a: select all visible ←: back / Enter")}`;
7787
+ const search = `${import_picocolors23.default.gray(BAR)} Search: ${searchValue}`;
7788
+ const help = `${import_picocolors23.default.gray(BAR)} ${import_picocolors23.default.dim("space: toggle doc type: search a: select all visible ←: back / Enter")}`;
7717
7789
  const body = visibleOptions2(this.fileCursor, this.filteredFiles.length, MAX_VISIBLE_FILE_ITEMS).map((option) => {
7718
7790
  if (option.kind === "ellipsis") {
7719
- return `${import_picocolors23.default.gray(BAR2)} ${import_picocolors23.default.dim(ELLIPSIS2)}`;
7791
+ return `${import_picocolors23.default.gray(BAR)} ${import_picocolors23.default.dim(ELLIPSIS)}`;
7720
7792
  }
7721
7793
  const file = this.filteredFiles[option.index];
7722
7794
  const isActive = option.index === this.fileCursor;
7723
7795
  const isSelected = this.selectedIds.has(file.id);
7724
- 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;
7796
+ 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;
7725
7797
  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;
7726
7798
  const hint = file.is_synced ? ` ${import_picocolors23.default.dim("(Already imported)")}` : "";
7727
- return `${import_picocolors23.default.gray(BAR2)} ${marker} ${label}${hint}`;
7799
+ return `${import_picocolors23.default.gray(BAR)} ${marker} ${label}${hint}`;
7728
7800
  });
7729
7801
  const content = body.length > 0 ? body.join(`
7730
- `) : `${import_picocolors23.default.gray(BAR2)} ${import_picocolors23.default.dim("No docs match your search.")}`;
7802
+ `) : `${import_picocolors23.default.gray(BAR)} ${import_picocolors23.default.dim("No docs match your search.")}`;
7731
7803
  return `${header}${back}
7732
- ${import_picocolors23.default.gray(BAR2)}
7804
+ ${import_picocolors23.default.gray(BAR)}
7733
7805
  ${search}
7734
- ${import_picocolors23.default.gray(BAR2)}
7806
+ ${import_picocolors23.default.gray(BAR)}
7735
7807
  ${content}
7736
- ${import_picocolors23.default.gray(BAR2)}
7808
+ ${import_picocolors23.default.gray(BAR)}
7737
7809
  ${help}
7738
- ${import_picocolors23.default.cyan(FOOTER2)}`;
7810
+ ${import_picocolors23.default.cyan(FOOTER)}`;
7739
7811
  }
7740
7812
  renderRepositoryMarker(state, isActive) {
7741
7813
  if (state === "all") {
7742
- return isActive ? import_picocolors23.default.cyan(CHECKBOX_ON2) : CHECKBOX_ON2;
7814
+ return isActive ? import_picocolors23.default.cyan(CHECKBOX_ON) : CHECKBOX_ON;
7743
7815
  }
7744
7816
  if (state === "partial") {
7745
7817
  return isActive ? import_picocolors23.default.cyan(CHECKBOX_PARTIAL) : CHECKBOX_PARTIAL;
7746
7818
  }
7747
7819
  if (state === "locked") {
7748
- return isActive ? import_picocolors23.default.cyan(CHECKBOX_OFF2) : import_picocolors23.default.dim(CHECKBOX_OFF2);
7820
+ return isActive ? import_picocolors23.default.cyan(CHECKBOX_OFF) : import_picocolors23.default.dim(CHECKBOX_OFF);
7749
7821
  }
7750
- return isActive ? import_picocolors23.default.cyan(CHECKBOX_OFF2) : CHECKBOX_OFF2;
7822
+ return isActive ? import_picocolors23.default.cyan(CHECKBOX_OFF) : CHECKBOX_OFF;
7751
7823
  }
7752
7824
  submitLabel() {
7753
7825
  const count = this.selectedIds.size;
@@ -7771,7 +7843,7 @@ async function stepImportGitHubDocs(cfg, opts = {}) {
7771
7843
  return { advance: false };
7772
7844
  }
7773
7845
  const trpc = createTypedClient(cfg);
7774
- const files = opts.waitForFreshDocs ? await waitForImportableGithubFiles(trpc, cfg.org_id, cfg.space_id) : await fetchImportableGithubFiles(trpc, cfg.space_id);
7846
+ const files = opts.waitForFreshDocs ? await waitForImportableGithubFiles(trpc, cfg.org_id, cfg.space_id, opts.expectedDataSourceIds) : await fetchImportableGithubFiles(trpc, cfg.space_id);
7775
7847
  if (files === null) {
7776
7848
  return { advance: false };
7777
7849
  }
@@ -7891,7 +7963,7 @@ Your GitHub docs are ready, and onboarding is complete.`);
7891
7963
  M2.warn(`Imported ${processed - failed} of ${total} doc${total === 1 ? "" : "s"}; ${failed} failed.
7892
7964
  You can review the failed docs later, but onboarding is complete.`);
7893
7965
  }
7894
- async function waitForImportableGithubFiles(trpc, orgID, spaceID) {
7966
+ async function waitForImportableGithubFiles(trpc, orgID, spaceID, expectedDataSourceIds) {
7895
7967
  while (true) {
7896
7968
  const spinner = Y2();
7897
7969
  spinner.start("Scanning repositories for markdown documents...");
@@ -7905,7 +7977,7 @@ async function waitForImportableGithubFiles(trpc, orgID, spaceID) {
7905
7977
  return latestFiles;
7906
7978
  }
7907
7979
  const dataSources = await fetchGitHubDataSources(trpc, orgID);
7908
- if (dataSources.length > 0 && dataSources.every((ds) => ds.is_indexed === true)) {
7980
+ if (isScanComplete(dataSources, expectedDataSourceIds)) {
7909
7981
  spinner.stop("No markdown docs found");
7910
7982
  return [];
7911
7983
  }
@@ -7928,6 +8000,24 @@ async function waitForImportableGithubFiles(trpc, orgID, spaceID) {
7928
8000
  }
7929
8001
  }
7930
8002
  }
8003
+ function isScanComplete(dataSources, expectedDataSourceIds) {
8004
+ if (expectedDataSourceIds && expectedDataSourceIds.length > 0) {
8005
+ const byId = new Map;
8006
+ for (const ds of dataSources) {
8007
+ if (ds.data_source_id)
8008
+ byId.set(ds.data_source_id, ds);
8009
+ }
8010
+ for (const id of expectedDataSourceIds) {
8011
+ const ds = byId.get(id);
8012
+ if (!ds)
8013
+ continue;
8014
+ if (ds.is_indexed !== true)
8015
+ return false;
8016
+ }
8017
+ return true;
8018
+ }
8019
+ return dataSources.length > 0 && dataSources.every((ds) => ds.is_indexed === true);
8020
+ }
7931
8021
  async function fetchGitHubDataSources(trpc, orgID) {
7932
8022
  try {
7933
8023
  const dataSources = await trpc.dataSource.list.query({
@@ -8275,9 +8365,14 @@ async function runSetup(opts = {}) {
8275
8365
  const apiClient = new Client(cfg);
8276
8366
  let cloudSetupContext = null;
8277
8367
  if (cfg.mode !== MODE_OSS) {
8368
+ const s = Y2();
8369
+ s.start("Loading your workspace...");
8278
8370
  cloudSetupContext = await resolveCloudSetupContext(cfg);
8279
- if (!cloudSetupContext)
8371
+ if (!cloudSetupContext) {
8372
+ s.stop("Workspace load failed");
8280
8373
  return;
8374
+ }
8375
+ s.stop("Workspace loaded");
8281
8376
  }
8282
8377
  if (cfg.mode !== MODE_OSS && cloudSetupContext?.kind === "onboarding") {
8283
8378
  const ok = await bindOnboardingDeployment(apiClient, cfg, cloudSetupContext.targetOrg ?? null);
@@ -8320,7 +8415,8 @@ async function runSetup(opts = {}) {
8320
8415
  }
8321
8416
  const { stepImportGitHubDocs: stepImportGitHubDocs2 } = await Promise.resolve().then(() => (init_github_doc_import_step(), exports_github_doc_import_step));
8322
8417
  const importResult = await stepImportGitHubDocs2(cfg, {
8323
- waitForFreshDocs: Boolean(connectResult.deployment_id)
8418
+ waitForFreshDocs: Boolean(connectResult.deployment_id),
8419
+ expectedDataSourceIds: connectResult.created_data_source_ids
8324
8420
  });
8325
8421
  if (!importResult.advance)
8326
8422
  return;
@@ -8351,6 +8447,12 @@ async function runSetup(opts = {}) {
8351
8447
  Se("\uD83C\uDF89 Setup complete!");
8352
8448
  }
8353
8449
  }
8450
+ function applyDeployment(cfg, d3) {
8451
+ cfg.deployment_id = d3.deployment_id;
8452
+ cfg.deployment_name = d3.name;
8453
+ cfg.org_id = d3.org_id;
8454
+ cfg.space_id = d3.space_id;
8455
+ }
8354
8456
  function applyModeOverride(cfg, opts) {
8355
8457
  if (!opts.mode)
8356
8458
  return;
@@ -8532,11 +8634,10 @@ async function bindOnboardingDeployment(apiClient, cfg, targetOrg) {
8532
8634
  return false;
8533
8635
  }
8534
8636
  cfg.mode = undefined;
8535
- cfg.deployment_id = deployment.deployment_id;
8536
- cfg.deployment_name = deployment.name;
8537
- cfg.org_id = deployment.org_id;
8538
- cfg.space_id = deployment.space_id;
8637
+ applyDeployment(cfg, deployment);
8539
8638
  logger.info("setup", `Bound onboarding context org=${targetOrg.org_id} deployment=${deployment.deployment_id}`);
8639
+ M2.success(`Organization
8640
+ ${dim(targetOrg.name)}`);
8540
8641
  return true;
8541
8642
  }
8542
8643
  async function resolveOnboardingDeployment(apiClient, targetOrg) {
@@ -8550,19 +8651,13 @@ async function resolveDeployment(apiClient, cfg, opts) {
8550
8651
  if (!d4)
8551
8652
  return false;
8552
8653
  cfg.mode = undefined;
8553
- cfg.deployment_id = d4.deployment_id;
8554
- cfg.deployment_name = d4.name;
8555
- cfg.org_id = d4.org_id;
8556
- cfg.space_id = d4.space_id;
8654
+ applyDeployment(cfg, d4);
8557
8655
  return true;
8558
8656
  }
8559
8657
  if (cfg.mode === MODE_OSS) {
8560
8658
  const deployments = await fetchDeployments(apiClient);
8561
8659
  if (deployments.length > 0) {
8562
- cfg.deployment_id = deployments[0].deployment_id;
8563
- cfg.deployment_name = deployments[0].name;
8564
- cfg.org_id = deployments[0].org_id;
8565
- cfg.space_id = deployments[0].space_id;
8660
+ applyDeployment(cfg, deployments[0]);
8566
8661
  }
8567
8662
  return true;
8568
8663
  }
@@ -8573,10 +8668,7 @@ async function resolveDeployment(apiClient, cfg, opts) {
8573
8668
  if (!d3)
8574
8669
  return false;
8575
8670
  cfg.mode = undefined;
8576
- cfg.deployment_id = d3.deployment_id;
8577
- cfg.deployment_name = d3.name;
8578
- cfg.org_id = d3.org_id;
8579
- cfg.space_id = d3.space_id;
8671
+ applyDeployment(cfg, d3);
8580
8672
  return true;
8581
8673
  }
8582
8674
  async function fetchDeployments(apiClient) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dosu/cli",
3
- "version": "0.11.0-alpha.3",
3
+ "version": "0.11.0-alpha.5",
4
4
  "type": "module",
5
5
  "description": "Dosu CLI - Manage MCP servers for AI tools",
6
6
  "license": "MIT",