@dosu/cli 0.14.1 → 0.15.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.
Files changed (2) hide show
  1. package/bin/dosu.js +1213 -94
  2. package/package.json +2 -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.14.1";
4344
+ var VERSION = "0.15.0";
4345
4345
 
4346
4346
  // src/debug/logger.ts
4347
4347
  import {
@@ -5165,17 +5165,17 @@ import y2 from "node:process";
5165
5165
  function ce() {
5166
5166
  return y2.platform !== "win32" ? y2.env.TERM !== "linux" : !!y2.env.CI || !!y2.env.WT_SESSION || !!y2.env.TERMINUS_SUBLIME || y2.env.ConEmuTask === "{cmd::Cmder}" || y2.env.TERM_PROGRAM === "Terminus-Sublime" || y2.env.TERM_PROGRAM === "vscode" || y2.env.TERM === "xterm-256color" || y2.env.TERM === "alacritty" || y2.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
5167
5167
  }
5168
- var import_picocolors8, import_sisteransi2, V2, u = (t, n) => V2 ? t : n, le, L2, W2, C2, ue, o, d2, k2, P2, A2, T, F, $e, _2, me, de, pe, q, D, U, K2, b2 = (t) => {
5168
+ var import_picocolors7, import_sisteransi2, V2, u = (t, n) => V2 ? t : n, le, L2, W2, C2, ue, o, d2, k2, P2, A2, T, F, $e, _2, me, de, pe, q, D, U, K2, b2 = (t) => {
5169
5169
  switch (t) {
5170
5170
  case "initial":
5171
5171
  case "active":
5172
- return import_picocolors8.default.cyan(le);
5172
+ return import_picocolors7.default.cyan(le);
5173
5173
  case "cancel":
5174
- return import_picocolors8.default.red(L2);
5174
+ return import_picocolors7.default.red(L2);
5175
5175
  case "error":
5176
- return import_picocolors8.default.yellow(W2);
5176
+ return import_picocolors7.default.yellow(W2);
5177
5177
  case "submit":
5178
- return import_picocolors8.default.green(C2);
5178
+ return import_picocolors7.default.green(C2);
5179
5179
  }
5180
5180
  }, G2 = (t) => {
5181
5181
  const { cursor: n, options: r, style: i } = t, s = t.maxItems ?? Number.POSITIVE_INFINITY, c = Math.max(process.stdout.rows - 4, 0), a = Math.min(c, Math.max(s, 5));
@@ -5184,23 +5184,23 @@ var import_picocolors8, import_sisteransi2, V2, u = (t, n) => V2 ? t : n, le, L2
5184
5184
  const $2 = a < r.length && l2 > 0, g2 = a < r.length && l2 + a < r.length;
5185
5185
  return r.slice(l2, l2 + a).map((p2, v, f) => {
5186
5186
  const j2 = v === 0 && $2, E = v === f.length - 1 && g2;
5187
- return j2 || E ? import_picocolors8.default.dim("...") : i(p2, v + l2 === n);
5187
+ return j2 || E ? import_picocolors7.default.dim("...") : i(p2, v + l2 === n);
5188
5188
  });
5189
5189
  }, ye = (t) => {
5190
5190
  const n = t.active ?? "Yes", r = t.inactive ?? "No";
5191
5191
  return new dD({ active: n, inactive: r, initialValue: t.initialValue ?? true, render() {
5192
- const i = `${import_picocolors8.default.gray(o)}
5192
+ const i = `${import_picocolors7.default.gray(o)}
5193
5193
  ${b2(this.state)} ${t.message}
5194
5194
  `, s = this.value ? n : r;
5195
5195
  switch (this.state) {
5196
5196
  case "submit":
5197
- return `${i}${import_picocolors8.default.gray(o)} ${import_picocolors8.default.dim(s)}`;
5197
+ return `${i}${import_picocolors7.default.gray(o)} ${import_picocolors7.default.dim(s)}`;
5198
5198
  case "cancel":
5199
- return `${i}${import_picocolors8.default.gray(o)} ${import_picocolors8.default.strikethrough(import_picocolors8.default.dim(s))}
5200
- ${import_picocolors8.default.gray(o)}`;
5199
+ return `${i}${import_picocolors7.default.gray(o)} ${import_picocolors7.default.strikethrough(import_picocolors7.default.dim(s))}
5200
+ ${import_picocolors7.default.gray(o)}`;
5201
5201
  default:
5202
- return `${i}${import_picocolors8.default.cyan(o)} ${this.value ? `${import_picocolors8.default.green(k2)} ${n}` : `${import_picocolors8.default.dim(P2)} ${import_picocolors8.default.dim(n)}`} ${import_picocolors8.default.dim("/")} ${this.value ? `${import_picocolors8.default.dim(P2)} ${import_picocolors8.default.dim(r)}` : `${import_picocolors8.default.green(k2)} ${r}`}
5203
- ${import_picocolors8.default.cyan(d2)}
5202
+ return `${i}${import_picocolors7.default.cyan(o)} ${this.value ? `${import_picocolors7.default.green(k2)} ${n}` : `${import_picocolors7.default.dim(P2)} ${import_picocolors7.default.dim(n)}`} ${import_picocolors7.default.dim("/")} ${this.value ? `${import_picocolors7.default.dim(P2)} ${import_picocolors7.default.dim(r)}` : `${import_picocolors7.default.green(k2)} ${r}`}
5203
+ ${import_picocolors7.default.cyan(d2)}
5204
5204
  `;
5205
5205
  }
5206
5206
  } }).prompt();
@@ -5209,43 +5209,43 @@ ${import_picocolors8.default.cyan(d2)}
5209
5209
  const s = r.label ?? String(r.value);
5210
5210
  switch (i) {
5211
5211
  case "selected":
5212
- return `${import_picocolors8.default.dim(s)}`;
5212
+ return `${import_picocolors7.default.dim(s)}`;
5213
5213
  case "active":
5214
- return `${import_picocolors8.default.green(k2)} ${s} ${r.hint ? import_picocolors8.default.dim(`(${r.hint})`) : ""}`;
5214
+ return `${import_picocolors7.default.green(k2)} ${s} ${r.hint ? import_picocolors7.default.dim(`(${r.hint})`) : ""}`;
5215
5215
  case "cancelled":
5216
- return `${import_picocolors8.default.strikethrough(import_picocolors8.default.dim(s))}`;
5216
+ return `${import_picocolors7.default.strikethrough(import_picocolors7.default.dim(s))}`;
5217
5217
  default:
5218
- return `${import_picocolors8.default.dim(P2)} ${import_picocolors8.default.dim(s)}`;
5218
+ return `${import_picocolors7.default.dim(P2)} ${import_picocolors7.default.dim(s)}`;
5219
5219
  }
5220
5220
  };
5221
5221
  return new LD({ options: t.options, initialValue: t.initialValue, render() {
5222
- const r = `${import_picocolors8.default.gray(o)}
5222
+ const r = `${import_picocolors7.default.gray(o)}
5223
5223
  ${b2(this.state)} ${t.message}
5224
5224
  `;
5225
5225
  switch (this.state) {
5226
5226
  case "submit":
5227
- return `${r}${import_picocolors8.default.gray(o)} ${n(this.options[this.cursor], "selected")}`;
5227
+ return `${r}${import_picocolors7.default.gray(o)} ${n(this.options[this.cursor], "selected")}`;
5228
5228
  case "cancel":
5229
- return `${r}${import_picocolors8.default.gray(o)} ${n(this.options[this.cursor], "cancelled")}
5230
- ${import_picocolors8.default.gray(o)}`;
5229
+ return `${r}${import_picocolors7.default.gray(o)} ${n(this.options[this.cursor], "cancelled")}
5230
+ ${import_picocolors7.default.gray(o)}`;
5231
5231
  default:
5232
- return `${r}${import_picocolors8.default.cyan(o)} ${G2({ cursor: this.cursor, options: this.options, maxItems: t.maxItems, style: (i, s) => n(i, s ? "active" : "inactive") }).join(`
5233
- ${import_picocolors8.default.cyan(o)} `)}
5234
- ${import_picocolors8.default.cyan(d2)}
5232
+ return `${r}${import_picocolors7.default.cyan(o)} ${G2({ cursor: this.cursor, options: this.options, maxItems: t.maxItems, style: (i, s) => n(i, s ? "active" : "inactive") }).join(`
5233
+ ${import_picocolors7.default.cyan(o)} `)}
5234
+ ${import_picocolors7.default.cyan(d2)}
5235
5235
  `;
5236
5236
  }
5237
5237
  } }).prompt();
5238
5238
  }, fe = (t) => {
5239
5239
  const n = (r, i) => {
5240
5240
  const s = r.label ?? String(r.value);
5241
- return i === "active" ? `${import_picocolors8.default.cyan(A2)} ${s} ${r.hint ? import_picocolors8.default.dim(`(${r.hint})`) : ""}` : i === "selected" ? `${import_picocolors8.default.green(T)} ${import_picocolors8.default.dim(s)} ${r.hint ? import_picocolors8.default.dim(`(${r.hint})`) : ""}` : i === "cancelled" ? `${import_picocolors8.default.strikethrough(import_picocolors8.default.dim(s))}` : i === "active-selected" ? `${import_picocolors8.default.green(T)} ${s} ${r.hint ? import_picocolors8.default.dim(`(${r.hint})`) : ""}` : i === "submitted" ? `${import_picocolors8.default.dim(s)}` : `${import_picocolors8.default.dim(F)} ${import_picocolors8.default.dim(s)}`;
5241
+ return i === "active" ? `${import_picocolors7.default.cyan(A2)} ${s} ${r.hint ? import_picocolors7.default.dim(`(${r.hint})`) : ""}` : i === "selected" ? `${import_picocolors7.default.green(T)} ${import_picocolors7.default.dim(s)} ${r.hint ? import_picocolors7.default.dim(`(${r.hint})`) : ""}` : i === "cancelled" ? `${import_picocolors7.default.strikethrough(import_picocolors7.default.dim(s))}` : i === "active-selected" ? `${import_picocolors7.default.green(T)} ${s} ${r.hint ? import_picocolors7.default.dim(`(${r.hint})`) : ""}` : i === "submitted" ? `${import_picocolors7.default.dim(s)}` : `${import_picocolors7.default.dim(F)} ${import_picocolors7.default.dim(s)}`;
5242
5242
  };
5243
5243
  return new SD({ options: t.options, initialValues: t.initialValues, required: t.required ?? true, cursorAt: t.cursorAt, validate(r) {
5244
5244
  if (this.required && r.length === 0)
5245
5245
  return `Please select at least one option.
5246
- ${import_picocolors8.default.reset(import_picocolors8.default.dim(`Press ${import_picocolors8.default.gray(import_picocolors8.default.bgWhite(import_picocolors8.default.inverse(" space ")))} to select, ${import_picocolors8.default.gray(import_picocolors8.default.bgWhite(import_picocolors8.default.inverse(" enter ")))} to submit`))}`;
5246
+ ${import_picocolors7.default.reset(import_picocolors7.default.dim(`Press ${import_picocolors7.default.gray(import_picocolors7.default.bgWhite(import_picocolors7.default.inverse(" space ")))} to select, ${import_picocolors7.default.gray(import_picocolors7.default.bgWhite(import_picocolors7.default.inverse(" enter ")))} to submit`))}`;
5247
5247
  }, render() {
5248
- const r = `${import_picocolors8.default.gray(o)}
5248
+ const r = `${import_picocolors7.default.gray(o)}
5249
5249
  ${b2(this.state)} ${t.message}
5250
5250
  `, i = (s, c) => {
5251
5251
  const a = this.value.includes(s.value);
@@ -5253,34 +5253,34 @@ ${b2(this.state)} ${t.message}
5253
5253
  };
5254
5254
  switch (this.state) {
5255
5255
  case "submit":
5256
- return `${r}${import_picocolors8.default.gray(o)} ${this.options.filter(({ value: s }) => this.value.includes(s)).map((s) => n(s, "submitted")).join(import_picocolors8.default.dim(", ")) || import_picocolors8.default.dim("none")}`;
5256
+ return `${r}${import_picocolors7.default.gray(o)} ${this.options.filter(({ value: s }) => this.value.includes(s)).map((s) => n(s, "submitted")).join(import_picocolors7.default.dim(", ")) || import_picocolors7.default.dim("none")}`;
5257
5257
  case "cancel": {
5258
- const s = this.options.filter(({ value: c }) => this.value.includes(c)).map((c) => n(c, "cancelled")).join(import_picocolors8.default.dim(", "));
5259
- return `${r}${import_picocolors8.default.gray(o)} ${s.trim() ? `${s}
5260
- ${import_picocolors8.default.gray(o)}` : ""}`;
5258
+ const s = this.options.filter(({ value: c }) => this.value.includes(c)).map((c) => n(c, "cancelled")).join(import_picocolors7.default.dim(", "));
5259
+ return `${r}${import_picocolors7.default.gray(o)} ${s.trim() ? `${s}
5260
+ ${import_picocolors7.default.gray(o)}` : ""}`;
5261
5261
  }
5262
5262
  case "error": {
5263
5263
  const s = this.error.split(`
5264
- `).map((c, a) => a === 0 ? `${import_picocolors8.default.yellow(d2)} ${import_picocolors8.default.yellow(c)}` : ` ${c}`).join(`
5264
+ `).map((c, a) => a === 0 ? `${import_picocolors7.default.yellow(d2)} ${import_picocolors7.default.yellow(c)}` : ` ${c}`).join(`
5265
5265
  `);
5266
- return `${r + import_picocolors8.default.yellow(o)} ${G2({ options: this.options, cursor: this.cursor, maxItems: t.maxItems, style: i }).join(`
5267
- ${import_picocolors8.default.yellow(o)} `)}
5266
+ return `${r + import_picocolors7.default.yellow(o)} ${G2({ options: this.options, cursor: this.cursor, maxItems: t.maxItems, style: i }).join(`
5267
+ ${import_picocolors7.default.yellow(o)} `)}
5268
5268
  ${s}
5269
5269
  `;
5270
5270
  }
5271
5271
  default:
5272
- return `${r}${import_picocolors8.default.cyan(o)} ${G2({ options: this.options, cursor: this.cursor, maxItems: t.maxItems, style: i }).join(`
5273
- ${import_picocolors8.default.cyan(o)} `)}
5274
- ${import_picocolors8.default.cyan(d2)}
5272
+ return `${r}${import_picocolors7.default.cyan(o)} ${G2({ options: this.options, cursor: this.cursor, maxItems: t.maxItems, style: i }).join(`
5273
+ ${import_picocolors7.default.cyan(o)} `)}
5274
+ ${import_picocolors7.default.cyan(d2)}
5275
5275
  `;
5276
5276
  }
5277
5277
  } }).prompt();
5278
5278
  }, Ie = (t = "") => {
5279
- process.stdout.write(`${import_picocolors8.default.gray(ue)} ${t}
5279
+ process.stdout.write(`${import_picocolors7.default.gray(ue)} ${t}
5280
5280
  `);
5281
5281
  }, Se = (t = "") => {
5282
- process.stdout.write(`${import_picocolors8.default.gray(o)}
5283
- ${import_picocolors8.default.gray(d2)} ${t}
5282
+ process.stdout.write(`${import_picocolors7.default.gray(o)}
5283
+ ${import_picocolors7.default.gray(d2)} ${t}
5284
5284
 
5285
5285
  `);
5286
5286
  }, M2, J2, Y2 = ({ indicator: t = "dots" } = {}) => {
@@ -5305,14 +5305,14 @@ ${import_picocolors8.default.gray(d2)} ${t}
5305
5305
  const h2 = (performance.now() - m2) / 1000, w2 = Math.floor(h2 / 60), I2 = Math.floor(h2 % 60);
5306
5306
  return w2 > 0 ? `[${w2}m ${I2}s]` : `[${I2}s]`;
5307
5307
  }, H2 = (m2 = "") => {
5308
- a = true, s = fD(), l2 = R2(m2), g2 = performance.now(), process.stdout.write(`${import_picocolors8.default.gray(o)}
5308
+ a = true, s = fD(), l2 = R2(m2), g2 = performance.now(), process.stdout.write(`${import_picocolors7.default.gray(o)}
5309
5309
  `);
5310
5310
  let h2 = 0, w2 = 0;
5311
5311
  j2(), c = setInterval(() => {
5312
5312
  if (i && l2 === $2)
5313
5313
  return;
5314
5314
  B2(), $2 = l2;
5315
- const I2 = import_picocolors8.default.magenta(n[h2]);
5315
+ const I2 = import_picocolors7.default.magenta(n[h2]);
5316
5316
  if (i)
5317
5317
  process.stdout.write(`${I2} ${l2}...`);
5318
5318
  else if (t === "timer")
@@ -5325,7 +5325,7 @@ ${import_picocolors8.default.gray(d2)} ${t}
5325
5325
  }, r);
5326
5326
  }, N2 = (m2 = "", h2 = 0) => {
5327
5327
  a = false, clearInterval(c), B2();
5328
- const w2 = h2 === 0 ? import_picocolors8.default.green(C2) : h2 === 1 ? import_picocolors8.default.red(L2) : import_picocolors8.default.red(W2);
5328
+ const w2 = h2 === 0 ? import_picocolors7.default.green(C2) : h2 === 1 ? import_picocolors7.default.red(L2) : import_picocolors7.default.red(W2);
5329
5329
  l2 = R2(m2 ?? l2), t === "timer" ? process.stdout.write(`${w2} ${l2} ${O2(g2)}
5330
5330
  `) : process.stdout.write(`${w2} ${l2}
5331
5331
  `), E(), s();
@@ -5337,7 +5337,7 @@ ${import_picocolors8.default.gray(d2)} ${t}
5337
5337
  var init_dist6 = __esm(() => {
5338
5338
  init_dist5();
5339
5339
  init_dist5();
5340
- import_picocolors8 = __toESM(require_picocolors(), 1);
5340
+ import_picocolors7 = __toESM(require_picocolors(), 1);
5341
5341
  import_sisteransi2 = __toESM(require_src(), 1);
5342
5342
  V2 = ce();
5343
5343
  le = u("◆", "*");
@@ -5361,30 +5361,30 @@ var init_dist6 = __esm(() => {
5361
5361
  D = u("◆", "*");
5362
5362
  U = u("▲", "!");
5363
5363
  K2 = u("■", "x");
5364
- M2 = { message: (t = "", { symbol: n = import_picocolors8.default.gray(o) } = {}) => {
5365
- const r = [`${import_picocolors8.default.gray(o)}`];
5364
+ M2 = { message: (t = "", { symbol: n = import_picocolors7.default.gray(o) } = {}) => {
5365
+ const r = [`${import_picocolors7.default.gray(o)}`];
5366
5366
  if (t) {
5367
5367
  const [i, ...s] = t.split(`
5368
5368
  `);
5369
- r.push(`${n} ${i}`, ...s.map((c) => `${import_picocolors8.default.gray(o)} ${c}`));
5369
+ r.push(`${n} ${i}`, ...s.map((c) => `${import_picocolors7.default.gray(o)} ${c}`));
5370
5370
  }
5371
5371
  process.stdout.write(`${r.join(`
5372
5372
  `)}
5373
5373
  `);
5374
5374
  }, info: (t) => {
5375
- M2.message(t, { symbol: import_picocolors8.default.blue(q) });
5375
+ M2.message(t, { symbol: import_picocolors7.default.blue(q) });
5376
5376
  }, success: (t) => {
5377
- M2.message(t, { symbol: import_picocolors8.default.green(D) });
5377
+ M2.message(t, { symbol: import_picocolors7.default.green(D) });
5378
5378
  }, step: (t) => {
5379
- M2.message(t, { symbol: import_picocolors8.default.green(C2) });
5379
+ M2.message(t, { symbol: import_picocolors7.default.green(C2) });
5380
5380
  }, warn: (t) => {
5381
- M2.message(t, { symbol: import_picocolors8.default.yellow(U) });
5381
+ M2.message(t, { symbol: import_picocolors7.default.yellow(U) });
5382
5382
  }, warning: (t) => {
5383
5383
  M2.warn(t);
5384
5384
  }, error: (t) => {
5385
- M2.message(t, { symbol: import_picocolors8.default.red(K2) });
5385
+ M2.message(t, { symbol: import_picocolors7.default.red(K2) });
5386
5386
  } };
5387
- J2 = `${import_picocolors8.default.gray(o)} `;
5387
+ J2 = `${import_picocolors7.default.gray(o)} `;
5388
5388
  });
5389
5389
 
5390
5390
  // src/insights/insights.ts
@@ -6655,9 +6655,532 @@ var init_skill = __esm(() => {
6655
6655
  import_picocolors10 = __toESM(require_picocolors(), 1);
6656
6656
  });
6657
6657
 
6658
+ // node_modules/imurmurhash/imurmurhash.js
6659
+ var require_imurmurhash = __commonJS((exports, module) => {
6660
+ (function() {
6661
+ var cache;
6662
+ function MurmurHash3(key, seed) {
6663
+ var m2 = this instanceof MurmurHash3 ? this : cache;
6664
+ m2.reset(seed);
6665
+ if (typeof key === "string" && key.length > 0) {
6666
+ m2.hash(key);
6667
+ }
6668
+ if (m2 !== this) {
6669
+ return m2;
6670
+ }
6671
+ }
6672
+ MurmurHash3.prototype.hash = function(key) {
6673
+ var h1, k1, i, top, len;
6674
+ len = key.length;
6675
+ this.len += len;
6676
+ k1 = this.k1;
6677
+ i = 0;
6678
+ switch (this.rem) {
6679
+ case 0:
6680
+ k1 ^= len > i ? key.charCodeAt(i++) & 65535 : 0;
6681
+ case 1:
6682
+ k1 ^= len > i ? (key.charCodeAt(i++) & 65535) << 8 : 0;
6683
+ case 2:
6684
+ k1 ^= len > i ? (key.charCodeAt(i++) & 65535) << 16 : 0;
6685
+ case 3:
6686
+ k1 ^= len > i ? (key.charCodeAt(i) & 255) << 24 : 0;
6687
+ k1 ^= len > i ? (key.charCodeAt(i++) & 65280) >> 8 : 0;
6688
+ }
6689
+ this.rem = len + this.rem & 3;
6690
+ len -= this.rem;
6691
+ if (len > 0) {
6692
+ h1 = this.h1;
6693
+ while (true) {
6694
+ k1 = k1 * 11601 + (k1 & 65535) * 3432906752 & 4294967295;
6695
+ k1 = k1 << 15 | k1 >>> 17;
6696
+ k1 = k1 * 13715 + (k1 & 65535) * 461832192 & 4294967295;
6697
+ h1 ^= k1;
6698
+ h1 = h1 << 13 | h1 >>> 19;
6699
+ h1 = h1 * 5 + 3864292196 & 4294967295;
6700
+ if (i >= len) {
6701
+ break;
6702
+ }
6703
+ k1 = key.charCodeAt(i++) & 65535 ^ (key.charCodeAt(i++) & 65535) << 8 ^ (key.charCodeAt(i++) & 65535) << 16;
6704
+ top = key.charCodeAt(i++);
6705
+ k1 ^= (top & 255) << 24 ^ (top & 65280) >> 8;
6706
+ }
6707
+ k1 = 0;
6708
+ switch (this.rem) {
6709
+ case 3:
6710
+ k1 ^= (key.charCodeAt(i + 2) & 65535) << 16;
6711
+ case 2:
6712
+ k1 ^= (key.charCodeAt(i + 1) & 65535) << 8;
6713
+ case 1:
6714
+ k1 ^= key.charCodeAt(i) & 65535;
6715
+ }
6716
+ this.h1 = h1;
6717
+ }
6718
+ this.k1 = k1;
6719
+ return this;
6720
+ };
6721
+ MurmurHash3.prototype.result = function() {
6722
+ var k1, h1;
6723
+ k1 = this.k1;
6724
+ h1 = this.h1;
6725
+ if (k1 > 0) {
6726
+ k1 = k1 * 11601 + (k1 & 65535) * 3432906752 & 4294967295;
6727
+ k1 = k1 << 15 | k1 >>> 17;
6728
+ k1 = k1 * 13715 + (k1 & 65535) * 461832192 & 4294967295;
6729
+ h1 ^= k1;
6730
+ }
6731
+ h1 ^= this.len;
6732
+ h1 ^= h1 >>> 16;
6733
+ h1 = h1 * 51819 + (h1 & 65535) * 2246770688 & 4294967295;
6734
+ h1 ^= h1 >>> 13;
6735
+ h1 = h1 * 44597 + (h1 & 65535) * 3266445312 & 4294967295;
6736
+ h1 ^= h1 >>> 16;
6737
+ return h1 >>> 0;
6738
+ };
6739
+ MurmurHash3.prototype.reset = function(seed) {
6740
+ this.h1 = typeof seed === "number" ? seed : 0;
6741
+ this.rem = this.k1 = this.len = 0;
6742
+ return this;
6743
+ };
6744
+ cache = new MurmurHash3;
6745
+ if (typeof module != "undefined") {
6746
+ module.exports = MurmurHash3;
6747
+ } else {
6748
+ this.MurmurHash3 = MurmurHash3;
6749
+ }
6750
+ })();
6751
+ });
6752
+
6753
+ // node_modules/signal-exit/dist/cjs/signals.js
6754
+ var require_signals = __commonJS((exports) => {
6755
+ Object.defineProperty(exports, "__esModule", { value: true });
6756
+ exports.signals = undefined;
6757
+ exports.signals = [];
6758
+ exports.signals.push("SIGHUP", "SIGINT", "SIGTERM");
6759
+ if (process.platform !== "win32") {
6760
+ exports.signals.push("SIGALRM", "SIGABRT", "SIGVTALRM", "SIGXCPU", "SIGXFSZ", "SIGUSR2", "SIGTRAP", "SIGSYS", "SIGQUIT", "SIGIOT");
6761
+ }
6762
+ if (process.platform === "linux") {
6763
+ exports.signals.push("SIGIO", "SIGPOLL", "SIGPWR", "SIGSTKFLT");
6764
+ }
6765
+ });
6766
+
6767
+ // node_modules/signal-exit/dist/cjs/index.js
6768
+ var require_cjs = __commonJS((exports) => {
6769
+ var _a;
6770
+ Object.defineProperty(exports, "__esModule", { value: true });
6771
+ exports.unload = exports.load = exports.onExit = exports.signals = undefined;
6772
+ var signals_js_1 = require_signals();
6773
+ Object.defineProperty(exports, "signals", { enumerable: true, get: function() {
6774
+ return signals_js_1.signals;
6775
+ } });
6776
+ var processOk = (process3) => !!process3 && typeof process3 === "object" && typeof process3.removeListener === "function" && typeof process3.emit === "function" && typeof process3.reallyExit === "function" && typeof process3.listeners === "function" && typeof process3.kill === "function" && typeof process3.pid === "number" && typeof process3.on === "function";
6777
+ var kExitEmitter = Symbol.for("signal-exit emitter");
6778
+ var global = globalThis;
6779
+ var ObjectDefineProperty = Object.defineProperty.bind(Object);
6780
+
6781
+ class Emitter {
6782
+ emitted = {
6783
+ afterExit: false,
6784
+ exit: false
6785
+ };
6786
+ listeners = {
6787
+ afterExit: [],
6788
+ exit: []
6789
+ };
6790
+ count = 0;
6791
+ id = Math.random();
6792
+ constructor() {
6793
+ if (global[kExitEmitter]) {
6794
+ return global[kExitEmitter];
6795
+ }
6796
+ ObjectDefineProperty(global, kExitEmitter, {
6797
+ value: this,
6798
+ writable: false,
6799
+ enumerable: false,
6800
+ configurable: false
6801
+ });
6802
+ }
6803
+ on(ev, fn) {
6804
+ this.listeners[ev].push(fn);
6805
+ }
6806
+ removeListener(ev, fn) {
6807
+ const list = this.listeners[ev];
6808
+ const i = list.indexOf(fn);
6809
+ if (i === -1) {
6810
+ return;
6811
+ }
6812
+ if (i === 0 && list.length === 1) {
6813
+ list.length = 0;
6814
+ } else {
6815
+ list.splice(i, 1);
6816
+ }
6817
+ }
6818
+ emit(ev, code, signal) {
6819
+ if (this.emitted[ev]) {
6820
+ return false;
6821
+ }
6822
+ this.emitted[ev] = true;
6823
+ let ret = false;
6824
+ for (const fn of this.listeners[ev]) {
6825
+ ret = fn(code, signal) === true || ret;
6826
+ }
6827
+ if (ev === "exit") {
6828
+ ret = this.emit("afterExit", code, signal) || ret;
6829
+ }
6830
+ return ret;
6831
+ }
6832
+ }
6833
+
6834
+ class SignalExitBase {
6835
+ }
6836
+ var signalExitWrap = (handler) => {
6837
+ return {
6838
+ onExit(cb, opts) {
6839
+ return handler.onExit(cb, opts);
6840
+ },
6841
+ load() {
6842
+ return handler.load();
6843
+ },
6844
+ unload() {
6845
+ return handler.unload();
6846
+ }
6847
+ };
6848
+ };
6849
+
6850
+ class SignalExitFallback extends SignalExitBase {
6851
+ onExit() {
6852
+ return () => {};
6853
+ }
6854
+ load() {}
6855
+ unload() {}
6856
+ }
6857
+
6858
+ class SignalExit extends SignalExitBase {
6859
+ #hupSig = process2.platform === "win32" ? "SIGINT" : "SIGHUP";
6860
+ #emitter = new Emitter;
6861
+ #process;
6862
+ #originalProcessEmit;
6863
+ #originalProcessReallyExit;
6864
+ #sigListeners = {};
6865
+ #loaded = false;
6866
+ constructor(process3) {
6867
+ super();
6868
+ this.#process = process3;
6869
+ this.#sigListeners = {};
6870
+ for (const sig of signals_js_1.signals) {
6871
+ this.#sigListeners[sig] = () => {
6872
+ const listeners = this.#process.listeners(sig);
6873
+ let { count } = this.#emitter;
6874
+ const p2 = process3;
6875
+ if (typeof p2.__signal_exit_emitter__ === "object" && typeof p2.__signal_exit_emitter__.count === "number") {
6876
+ count += p2.__signal_exit_emitter__.count;
6877
+ }
6878
+ if (listeners.length === count) {
6879
+ this.unload();
6880
+ const ret = this.#emitter.emit("exit", null, sig);
6881
+ const s = sig === "SIGHUP" ? this.#hupSig : sig;
6882
+ if (!ret)
6883
+ process3.kill(process3.pid, s);
6884
+ }
6885
+ };
6886
+ }
6887
+ this.#originalProcessReallyExit = process3.reallyExit;
6888
+ this.#originalProcessEmit = process3.emit;
6889
+ }
6890
+ onExit(cb, opts) {
6891
+ if (!processOk(this.#process)) {
6892
+ return () => {};
6893
+ }
6894
+ if (this.#loaded === false) {
6895
+ this.load();
6896
+ }
6897
+ const ev = opts?.alwaysLast ? "afterExit" : "exit";
6898
+ this.#emitter.on(ev, cb);
6899
+ return () => {
6900
+ this.#emitter.removeListener(ev, cb);
6901
+ if (this.#emitter.listeners["exit"].length === 0 && this.#emitter.listeners["afterExit"].length === 0) {
6902
+ this.unload();
6903
+ }
6904
+ };
6905
+ }
6906
+ load() {
6907
+ if (this.#loaded) {
6908
+ return;
6909
+ }
6910
+ this.#loaded = true;
6911
+ this.#emitter.count += 1;
6912
+ for (const sig of signals_js_1.signals) {
6913
+ try {
6914
+ const fn = this.#sigListeners[sig];
6915
+ if (fn)
6916
+ this.#process.on(sig, fn);
6917
+ } catch (_3) {}
6918
+ }
6919
+ this.#process.emit = (ev, ...a) => {
6920
+ return this.#processEmit(ev, ...a);
6921
+ };
6922
+ this.#process.reallyExit = (code) => {
6923
+ return this.#processReallyExit(code);
6924
+ };
6925
+ }
6926
+ unload() {
6927
+ if (!this.#loaded) {
6928
+ return;
6929
+ }
6930
+ this.#loaded = false;
6931
+ signals_js_1.signals.forEach((sig) => {
6932
+ const listener = this.#sigListeners[sig];
6933
+ if (!listener) {
6934
+ throw new Error("Listener not defined for signal: " + sig);
6935
+ }
6936
+ try {
6937
+ this.#process.removeListener(sig, listener);
6938
+ } catch (_3) {}
6939
+ });
6940
+ this.#process.emit = this.#originalProcessEmit;
6941
+ this.#process.reallyExit = this.#originalProcessReallyExit;
6942
+ this.#emitter.count -= 1;
6943
+ }
6944
+ #processReallyExit(code) {
6945
+ if (!processOk(this.#process)) {
6946
+ return 0;
6947
+ }
6948
+ this.#process.exitCode = code || 0;
6949
+ this.#emitter.emit("exit", this.#process.exitCode, null);
6950
+ return this.#originalProcessReallyExit.call(this.#process, this.#process.exitCode);
6951
+ }
6952
+ #processEmit(ev, ...args) {
6953
+ const og = this.#originalProcessEmit;
6954
+ if (ev === "exit" && processOk(this.#process)) {
6955
+ if (typeof args[0] === "number") {
6956
+ this.#process.exitCode = args[0];
6957
+ }
6958
+ const ret = og.call(this.#process, ev, ...args);
6959
+ this.#emitter.emit("exit", this.#process.exitCode, null);
6960
+ return ret;
6961
+ } else {
6962
+ return og.call(this.#process, ev, ...args);
6963
+ }
6964
+ }
6965
+ }
6966
+ var process2 = globalThis.process;
6967
+ _a = signalExitWrap(processOk(process2) ? new SignalExit(process2) : new SignalExitFallback), exports.onExit = _a.onExit, exports.load = _a.load, exports.unload = _a.unload;
6968
+ });
6969
+
6970
+ // node_modules/write-file-atomic/lib/index.js
6971
+ var require_lib = __commonJS((exports, module) => {
6972
+ var __filename = "/home/runner/work/dosu-cli/dosu-cli/node_modules/write-file-atomic/lib/index.js";
6973
+ module.exports = writeFile;
6974
+ module.exports.sync = writeFileSync4;
6975
+ module.exports._getTmpname = getTmpname;
6976
+ module.exports._cleanupOnExit = cleanupOnExit;
6977
+ var fs = __require("fs");
6978
+ var MurmurHash3 = require_imurmurhash();
6979
+ var { onExit } = require_cjs();
6980
+ var path = __require("path");
6981
+ var { promisify } = __require("util");
6982
+ var activeFiles = {};
6983
+ var threadId = function getId() {
6984
+ try {
6985
+ const workerThreads = __require("worker_threads");
6986
+ return workerThreads.threadId;
6987
+ } catch (e2) {
6988
+ return 0;
6989
+ }
6990
+ }();
6991
+ var invocations = 0;
6992
+ function getTmpname(filename) {
6993
+ return filename + "." + MurmurHash3(__filename).hash(String(process.pid)).hash(String(threadId)).hash(String(++invocations)).result();
6994
+ }
6995
+ function cleanupOnExit(tmpfile) {
6996
+ return () => {
6997
+ try {
6998
+ fs.unlinkSync(typeof tmpfile === "function" ? tmpfile() : tmpfile);
6999
+ } catch {}
7000
+ };
7001
+ }
7002
+ function serializeActiveFile(absoluteName) {
7003
+ return new Promise((resolve) => {
7004
+ if (!activeFiles[absoluteName]) {
7005
+ activeFiles[absoluteName] = [];
7006
+ }
7007
+ activeFiles[absoluteName].push(resolve);
7008
+ if (activeFiles[absoluteName].length === 1) {
7009
+ resolve();
7010
+ }
7011
+ });
7012
+ }
7013
+ function isChownErrOk(err) {
7014
+ if (err.code === "ENOSYS") {
7015
+ return true;
7016
+ }
7017
+ const nonroot = !process.getuid || process.getuid() !== 0;
7018
+ if (nonroot) {
7019
+ if (err.code === "EINVAL" || err.code === "EPERM") {
7020
+ return true;
7021
+ }
7022
+ }
7023
+ return false;
7024
+ }
7025
+ async function writeFileAsync(filename, data, options = {}) {
7026
+ if (typeof options === "string") {
7027
+ options = { encoding: options };
7028
+ }
7029
+ let fd;
7030
+ let tmpfile;
7031
+ const removeOnExitHandler = onExit(cleanupOnExit(() => tmpfile));
7032
+ const absoluteName = path.resolve(filename);
7033
+ try {
7034
+ await serializeActiveFile(absoluteName);
7035
+ const truename = await promisify(fs.realpath)(filename).catch(() => filename);
7036
+ tmpfile = getTmpname(truename);
7037
+ if (!options.mode || !options.chown) {
7038
+ const stats = await promisify(fs.stat)(truename).catch(() => {});
7039
+ if (stats) {
7040
+ if (options.mode == null) {
7041
+ options.mode = stats.mode;
7042
+ }
7043
+ if (options.chown == null && process.getuid) {
7044
+ options.chown = { uid: stats.uid, gid: stats.gid };
7045
+ }
7046
+ }
7047
+ }
7048
+ fd = await promisify(fs.open)(tmpfile, "w", options.mode);
7049
+ if (options.tmpfileCreated) {
7050
+ await options.tmpfileCreated(tmpfile);
7051
+ }
7052
+ if (ArrayBuffer.isView(data)) {
7053
+ await promisify(fs.write)(fd, data, 0, data.length, 0);
7054
+ } else if (data != null) {
7055
+ await promisify(fs.write)(fd, String(data), 0, String(options.encoding || "utf8"));
7056
+ }
7057
+ if (options.fsync !== false) {
7058
+ await promisify(fs.fsync)(fd);
7059
+ }
7060
+ await promisify(fs.close)(fd);
7061
+ fd = null;
7062
+ if (options.chown) {
7063
+ await promisify(fs.chown)(tmpfile, options.chown.uid, options.chown.gid).catch((err) => {
7064
+ if (!isChownErrOk(err)) {
7065
+ throw err;
7066
+ }
7067
+ });
7068
+ }
7069
+ if (options.mode) {
7070
+ await promisify(fs.chmod)(tmpfile, options.mode).catch((err) => {
7071
+ if (!isChownErrOk(err)) {
7072
+ throw err;
7073
+ }
7074
+ });
7075
+ }
7076
+ await promisify(fs.rename)(tmpfile, truename);
7077
+ } finally {
7078
+ if (fd) {
7079
+ await promisify(fs.close)(fd).catch(() => {});
7080
+ }
7081
+ removeOnExitHandler();
7082
+ await promisify(fs.unlink)(tmpfile).catch(() => {});
7083
+ activeFiles[absoluteName].shift();
7084
+ if (activeFiles[absoluteName].length > 0) {
7085
+ activeFiles[absoluteName][0]();
7086
+ } else {
7087
+ delete activeFiles[absoluteName];
7088
+ }
7089
+ }
7090
+ }
7091
+ async function writeFile(filename, data, options, callback) {
7092
+ if (options instanceof Function) {
7093
+ callback = options;
7094
+ options = {};
7095
+ }
7096
+ const promise = writeFileAsync(filename, data, options);
7097
+ if (callback) {
7098
+ try {
7099
+ const result = await promise;
7100
+ return callback(result);
7101
+ } catch (err) {
7102
+ return callback(err);
7103
+ }
7104
+ }
7105
+ return promise;
7106
+ }
7107
+ function writeFileSync4(filename, data, options) {
7108
+ if (typeof options === "string") {
7109
+ options = { encoding: options };
7110
+ } else if (!options) {
7111
+ options = {};
7112
+ }
7113
+ try {
7114
+ filename = fs.realpathSync(filename);
7115
+ } catch (ex) {}
7116
+ const tmpfile = getTmpname(filename);
7117
+ if (!options.mode || !options.chown) {
7118
+ try {
7119
+ const stats = fs.statSync(filename);
7120
+ options = Object.assign({}, options);
7121
+ if (!options.mode) {
7122
+ options.mode = stats.mode;
7123
+ }
7124
+ if (!options.chown && process.getuid) {
7125
+ options.chown = { uid: stats.uid, gid: stats.gid };
7126
+ }
7127
+ } catch (ex) {}
7128
+ }
7129
+ let fd;
7130
+ const cleanup = cleanupOnExit(tmpfile);
7131
+ const removeOnExitHandler = onExit(cleanup);
7132
+ let threw = true;
7133
+ try {
7134
+ fd = fs.openSync(tmpfile, "w", options.mode || 438);
7135
+ if (options.tmpfileCreated) {
7136
+ options.tmpfileCreated(tmpfile);
7137
+ }
7138
+ if (ArrayBuffer.isView(data)) {
7139
+ fs.writeSync(fd, data, 0, data.length, 0);
7140
+ } else if (data != null) {
7141
+ fs.writeSync(fd, String(data), 0, String(options.encoding || "utf8"));
7142
+ }
7143
+ if (options.fsync !== false) {
7144
+ fs.fsyncSync(fd);
7145
+ }
7146
+ fs.closeSync(fd);
7147
+ fd = null;
7148
+ if (options.chown) {
7149
+ try {
7150
+ fs.chownSync(tmpfile, options.chown.uid, options.chown.gid);
7151
+ } catch (err) {
7152
+ if (!isChownErrOk(err)) {
7153
+ throw err;
7154
+ }
7155
+ }
7156
+ }
7157
+ if (options.mode) {
7158
+ try {
7159
+ fs.chmodSync(tmpfile, options.mode);
7160
+ } catch (err) {
7161
+ if (!isChownErrOk(err)) {
7162
+ throw err;
7163
+ }
7164
+ }
7165
+ }
7166
+ fs.renameSync(tmpfile, filename);
7167
+ threw = false;
7168
+ } finally {
7169
+ if (fd) {
7170
+ try {
7171
+ fs.closeSync(fd);
7172
+ } catch (ex) {}
7173
+ }
7174
+ removeOnExitHandler();
7175
+ if (threw) {
7176
+ cleanup();
7177
+ }
7178
+ }
7179
+ }
7180
+ });
7181
+
6658
7182
  // src/mcp/config-helpers.ts
6659
7183
  import { existsSync as existsSync4, mkdirSync as mkdirSync4, readFileSync as readFileSync5 } from "node:fs";
6660
- import { createRequire as createRequire2 } from "node:module";
6661
7184
  import { dirname } from "node:path";
6662
7185
  function mcpURL(deploymentID) {
6663
7186
  return `${getBackendURL()}/v1/mcp/deployments/${deploymentID}`;
@@ -6772,10 +7295,10 @@ function removeJSONServer(configPath, topKey) {
6772
7295
  }
6773
7296
  saveJSONConfig(configPath, jsonCfg);
6774
7297
  }
6775
- var require2, writeFileAtomic;
7298
+ var import_write_file_atomic, writeFileAtomic;
6776
7299
  var init_config_helpers = __esm(() => {
6777
- require2 = createRequire2(import.meta.url);
6778
- writeFileAtomic = require2("write-file-atomic");
7300
+ import_write_file_atomic = __toESM(require_lib(), 1);
7301
+ writeFileAtomic = import_write_file_atomic.default;
6779
7302
  });
6780
7303
 
6781
7304
  // src/mcp/detect.ts
@@ -10982,6 +11505,486 @@ var init_tui = __esm(() => {
10982
11505
  import_picocolors25 = __toESM(require_picocolors(), 1);
10983
11506
  });
10984
11507
 
11508
+ // src/auth/ticket.ts
11509
+ function buildTicketAuthURL(ticket) {
11510
+ const base = getWebAppURL();
11511
+ const params = new URLSearchParams({ ticket });
11512
+ return `${base}/cli/auth?${params}`;
11513
+ }
11514
+ async function mintTicket() {
11515
+ const url = `${getBackendURL()}/v1/cli/auth/tickets`;
11516
+ logger.debug("auth.ticket", `Minting ticket via ${url}`);
11517
+ const resp = await fetchWithTimeout(url, { method: "POST" });
11518
+ if (resp.status !== 200 && resp.status !== 201) {
11519
+ const detail = await readErrorBody2(resp);
11520
+ throw new Error(`failed to mint ticket (status ${resp.status}): ${detail}`);
11521
+ }
11522
+ const data = await resp.json();
11523
+ logger.info("auth.ticket", `Minted ticket (ttl=${data.expires_in}s)`);
11524
+ return {
11525
+ ticket: data.ticket,
11526
+ expires_in: data.expires_in,
11527
+ url: buildTicketAuthURL(data.ticket)
11528
+ };
11529
+ }
11530
+ async function exchangeTicket(ticket) {
11531
+ const path2 = `/v1/cli/auth/tickets/${encodeURIComponent(ticket)}/exchange`;
11532
+ const url = `${getBackendURL()}${path2}`;
11533
+ logger.debug("auth.ticket", `Exchanging ticket via ${url}`);
11534
+ const resp = await fetchWithTimeout(url, { method: "POST" });
11535
+ if (resp.status !== 200) {
11536
+ const detail = await readErrorBody2(resp);
11537
+ throw new Error(`ticket exchange failed (status ${resp.status}): ${detail}`);
11538
+ }
11539
+ const data = await resp.json();
11540
+ return {
11541
+ status: data.status,
11542
+ access_token: data.access_token ?? undefined,
11543
+ refresh_token: data.refresh_token ?? undefined,
11544
+ expires_in: data.expires_in ?? undefined,
11545
+ email: data.email ?? undefined
11546
+ };
11547
+ }
11548
+ async function fetchWithTimeout(url, init) {
11549
+ const controller = new AbortController;
11550
+ const timeout = setTimeout(() => controller.abort(), 1e4);
11551
+ try {
11552
+ return await fetch(url, { ...init, signal: controller.signal });
11553
+ } finally {
11554
+ clearTimeout(timeout);
11555
+ }
11556
+ }
11557
+ async function readErrorBody2(resp) {
11558
+ try {
11559
+ return (await resp.text()).slice(0, 512);
11560
+ } catch {
11561
+ return "";
11562
+ }
11563
+ }
11564
+ var init_ticket = __esm(() => {
11565
+ init_logger();
11566
+ });
11567
+
11568
+ // src/agent/output.ts
11569
+ var exports_output = {};
11570
+ __export(exports_output, {
11571
+ emitStep: () => emitStep,
11572
+ emitNeedUserAction: () => emitNeedUserAction,
11573
+ emitJSONLine: () => emitJSONLine,
11574
+ emitError: () => emitError
11575
+ });
11576
+ function emitJSONLine(value) {
11577
+ console.log(JSON.stringify(value));
11578
+ }
11579
+ function emitNeedUserAction(opts) {
11580
+ emitJSONLine({
11581
+ step: opts.step,
11582
+ status: "need_user_action",
11583
+ url: opts.url,
11584
+ ticket: opts.ticket,
11585
+ resume_command: opts.resume_command,
11586
+ expires_in: opts.expires_in,
11587
+ agent_next_steps: opts.agent_next_steps
11588
+ });
11589
+ }
11590
+ function emitError(opts) {
11591
+ emitJSONLine({
11592
+ step: opts.step,
11593
+ status: "error",
11594
+ reason: opts.reason,
11595
+ agent_next_steps: opts.agent_next_steps
11596
+ });
11597
+ }
11598
+ function emitStep(opts) {
11599
+ const { step, status = "ok", ...rest } = opts;
11600
+ emitJSONLine({ step, status, ...rest });
11601
+ }
11602
+
11603
+ // src/agent/login-commands.ts
11604
+ var exports_login_commands = {};
11605
+ __export(exports_login_commands, {
11606
+ runLoginRequest: () => runLoginRequest,
11607
+ runLoginCheck: () => runLoginCheck
11608
+ });
11609
+ async function runLoginRequest(opts) {
11610
+ try {
11611
+ const minted = await mintTicket();
11612
+ const checkCommand = `${CHECK_COMMAND_PREFIX} ${minted.ticket}${opts.json ? " --json" : ""}`;
11613
+ if (opts.json) {
11614
+ emitJSONLine({
11615
+ ticket: minted.ticket,
11616
+ url: minted.url,
11617
+ check_command: checkCommand,
11618
+ expires_in: minted.expires_in,
11619
+ agent_next_steps: "Give the URL to the user so they can authorize. Once the user confirms they've signed in, run check_command to retrieve the token."
11620
+ });
11621
+ } else {
11622
+ console.log("Open this URL in your browser to authorize:");
11623
+ console.log(` ${minted.url}`);
11624
+ console.log("");
11625
+ console.log("After signing in, complete the login with:");
11626
+ console.log(` ${checkCommand}`);
11627
+ console.log("");
11628
+ console.log(`Ticket expires in ${Math.floor(minted.expires_in / 60)} minutes.`);
11629
+ }
11630
+ return 0;
11631
+ } catch (err) {
11632
+ const msg = err instanceof Error ? err.message : String(err);
11633
+ if (opts.json) {
11634
+ emitError({
11635
+ step: "request",
11636
+ reason: "mint_failed",
11637
+ agent_next_steps: `Could not mint a login ticket: ${msg}. Check connectivity and retry.`
11638
+ });
11639
+ } else {
11640
+ console.error(`Failed to mint login ticket: ${msg}`);
11641
+ }
11642
+ return 1;
11643
+ }
11644
+ }
11645
+ async function runLoginCheck(opts) {
11646
+ let result;
11647
+ try {
11648
+ result = await exchangeTicket(opts.ticket);
11649
+ } catch (err) {
11650
+ const msg = err instanceof Error ? err.message : String(err);
11651
+ if (opts.json) {
11652
+ emitError({
11653
+ step: "check",
11654
+ reason: "exchange_failed",
11655
+ agent_next_steps: `Ticket exchange failed: ${msg}. Retry, or run 'dosu login --request' to get a fresh ticket.`
11656
+ });
11657
+ } else {
11658
+ console.error(`Ticket exchange failed: ${msg}`);
11659
+ }
11660
+ return 1;
11661
+ }
11662
+ if (result.status === "authenticated") {
11663
+ const cfg = loadConfig();
11664
+ cfg.access_token = result.access_token ?? "";
11665
+ cfg.refresh_token = result.refresh_token ?? "";
11666
+ cfg.expires_at = Math.floor(Date.now() / 1000) + (result.expires_in ?? 3600);
11667
+ saveConfig(cfg);
11668
+ logger.info("auth.ticket", "Ticket redeemed via dosu login --check");
11669
+ if (opts.json) {
11670
+ emitStep({
11671
+ step: "check",
11672
+ status: "authenticated",
11673
+ email: result.email,
11674
+ agent_next_steps: "Authentication complete. You can now run authenticated commands like 'dosu setup' or 'dosu status'."
11675
+ });
11676
+ } else {
11677
+ console.log("Successfully authenticated!");
11678
+ if (result.email)
11679
+ console.log(`Signed in as ${result.email}`);
11680
+ }
11681
+ return 0;
11682
+ }
11683
+ if (result.status === "pending") {
11684
+ if (opts.json) {
11685
+ emitStep({
11686
+ step: "check",
11687
+ status: "pending",
11688
+ ticket: opts.ticket,
11689
+ agent_next_steps: "User hasn't completed sign-in yet. Ask the user to confirm they've signed in via the URL from --request, then run this check command again."
11690
+ });
11691
+ } else {
11692
+ console.log("Still waiting for the user to complete sign-in. Run --check again later.");
11693
+ }
11694
+ return 0;
11695
+ }
11696
+ if (opts.json) {
11697
+ emitStep({
11698
+ step: "check",
11699
+ status: "expired",
11700
+ agent_next_steps: "Ticket has expired or was already redeemed. Run 'dosu login --request --json' to get a fresh ticket."
11701
+ });
11702
+ } else {
11703
+ console.error("Ticket has expired or was already used. Run 'dosu login --request' for a new one.");
11704
+ }
11705
+ return 1;
11706
+ }
11707
+ var CHECK_COMMAND_PREFIX = "dosu login --check";
11708
+ var init_login_commands = __esm(() => {
11709
+ init_ticket();
11710
+ init_config();
11711
+ init_logger();
11712
+ });
11713
+
11714
+ // src/agent/flow.ts
11715
+ var exports_flow3 = {};
11716
+ __export(exports_flow3, {
11717
+ runAgentSetup: () => runAgentSetup,
11718
+ listAgentSupportedToolIDs: () => listAgentSupportedToolIDs,
11719
+ buildResumeCommand: () => buildResumeCommand
11720
+ });
11721
+ async function runAgentSetup(opts) {
11722
+ const provider = allSetupProviders().find((p2) => p2.id() === opts.tool.toLowerCase());
11723
+ if (!provider) {
11724
+ const available = allSetupProviders().filter((p2) => !isStdioOnly(p2)).map((p2) => p2.id()).join(", ");
11725
+ emitError({
11726
+ step: "setup",
11727
+ reason: "unknown_tool",
11728
+ agent_next_steps: `'${opts.tool}' is not a supported tool. Choose one of: ${available}. Re-run with --tool <id>.`
11729
+ });
11730
+ return 2;
11731
+ }
11732
+ if (isStdioOnly(provider)) {
11733
+ emitError({
11734
+ step: "setup",
11735
+ reason: "tool_unsupported_in_agent_mode",
11736
+ agent_next_steps: `${provider.name()} is not supported by agent setup. Tell the user to run 'dosu mcp add ${provider.id()}' manually after signing in.`
11737
+ });
11738
+ return 2;
11739
+ }
11740
+ let cfg = loadConfig();
11741
+ if (opts.loginTicket) {
11742
+ const redeemed = await redeemTicket(opts.loginTicket, cfg);
11743
+ if (redeemed.code !== 0 || redeemed.exit)
11744
+ return redeemed.code;
11745
+ cfg = redeemed.cfg;
11746
+ } else {
11747
+ const verified = await verifyOrMint(cfg, opts);
11748
+ if (verified.code !== 0 || verified.exit)
11749
+ return verified.code;
11750
+ cfg = verified.cfg;
11751
+ }
11752
+ const client = new Client(cfg);
11753
+ const deploymentResult = await resolveDeployment2(client, cfg, opts);
11754
+ if (deploymentResult.code !== 0)
11755
+ return deploymentResult.code;
11756
+ cfg = deploymentResult.cfg;
11757
+ const keyResult = await ensureAPIKey(client, cfg);
11758
+ if (keyResult.code !== 0)
11759
+ return keyResult.code;
11760
+ cfg = keyResult.cfg;
11761
+ try {
11762
+ provider.install(cfg, true);
11763
+ emitStep({
11764
+ step: "mcp_install",
11765
+ tool: provider.id(),
11766
+ tool_name: provider.name(),
11767
+ config_path: provider.globalConfigPath()
11768
+ });
11769
+ } catch (err) {
11770
+ emitError({
11771
+ step: "mcp_install",
11772
+ reason: "install_failed",
11773
+ agent_next_steps: `Failed to install Dosu MCP into ${provider.name()}: ${err instanceof Error ? err.message : String(err)}. Tell the user to retry or run 'dosu mcp add ${provider.id()}' manually.`
11774
+ });
11775
+ return 1;
11776
+ }
11777
+ emitStep({
11778
+ step: "done",
11779
+ agent_next_steps: `Dosu MCP is configured for ${provider.name()}. Tell the user setup is complete and they can ask their agent a Dosu question. Run 'dosu status' to verify.`
11780
+ });
11781
+ return 0;
11782
+ }
11783
+ async function redeemTicket(ticket, cfg) {
11784
+ try {
11785
+ const result = await exchangeTicket(ticket);
11786
+ if (result.status === "expired") {
11787
+ emitError({
11788
+ step: "auth",
11789
+ reason: "ticket_expired",
11790
+ agent_next_steps: "Ticket expired or already redeemed. Re-run the agent setup command without --login-ticket to mint a fresh one."
11791
+ });
11792
+ return { code: 1, cfg };
11793
+ }
11794
+ if (result.status === "pending") {
11795
+ emitStep({
11796
+ step: "auth",
11797
+ status: "pending",
11798
+ agent_next_steps: "User hasn't completed sign-in yet. Ask the user to confirm they've signed in, then run the same command again."
11799
+ });
11800
+ return { code: 0, cfg, exit: true };
11801
+ }
11802
+ cfg.access_token = result.access_token ?? "";
11803
+ cfg.refresh_token = result.refresh_token ?? "";
11804
+ cfg.expires_at = Math.floor(Date.now() / 1000) + (result.expires_in ?? 3600);
11805
+ saveConfig(cfg);
11806
+ logger.info("agent.flow", "Ticket redeemed; session saved");
11807
+ emitStep({ step: "auth", email: result.email });
11808
+ return { code: 0, cfg };
11809
+ } catch (err) {
11810
+ emitError({
11811
+ step: "auth",
11812
+ reason: "ticket_exchange_failed",
11813
+ agent_next_steps: `Failed to exchange ticket: ${err instanceof Error ? err.message : String(err)}. Re-run without --login-ticket to start over.`
11814
+ });
11815
+ return { code: 1, cfg };
11816
+ }
11817
+ }
11818
+ async function verifyOrMint(cfg, opts) {
11819
+ if (cfg.access_token) {
11820
+ try {
11821
+ const client = new Client(cfg);
11822
+ const resp = await client.doRequestRaw("GET", "/v1/mcp/deployments");
11823
+ if (resp.status === 200) {
11824
+ emitStep({ step: "auth" });
11825
+ return { code: 0, cfg };
11826
+ }
11827
+ try {
11828
+ await client.refreshToken();
11829
+ const fresh = loadConfig();
11830
+ emitStep({ step: "auth" });
11831
+ return { code: 0, cfg: fresh };
11832
+ } catch {}
11833
+ } catch {}
11834
+ }
11835
+ try {
11836
+ const minted = await mintTicket();
11837
+ emitNeedUserAction({
11838
+ step: "auth",
11839
+ url: minted.url,
11840
+ ticket: minted.ticket,
11841
+ resume_command: buildResumeCommand(opts.tool, minted.ticket, opts.deploymentID),
11842
+ expires_in: minted.expires_in,
11843
+ agent_next_steps: "Give the URL to the user so they can sign in. Wait for the user to confirm they've signed in, then run resume_command to finish setup."
11844
+ });
11845
+ return { code: 0, cfg, exit: true };
11846
+ } catch (err) {
11847
+ emitError({
11848
+ step: "auth",
11849
+ reason: "ticket_mint_failed",
11850
+ agent_next_steps: `Could not mint a login ticket: ${err instanceof Error ? err.message : String(err)}. Check connectivity and retry.`
11851
+ });
11852
+ return { code: 1, cfg };
11853
+ }
11854
+ }
11855
+ async function resolveDeployment2(client, cfg, opts) {
11856
+ if (opts.deploymentID) {
11857
+ try {
11858
+ const deployments = await client.getDeployments();
11859
+ const d3 = deployments.find((dep) => dep.deployment_id === opts.deploymentID);
11860
+ if (!d3) {
11861
+ emitError({
11862
+ step: "deployment",
11863
+ reason: "not_found",
11864
+ agent_next_steps: `Deployment '${opts.deploymentID}' is not accessible. Run 'dosu deployments list --json' to see options and try again with a valid id.`
11865
+ });
11866
+ return { code: 1, cfg };
11867
+ }
11868
+ cfg.deployment_id = d3.deployment_id;
11869
+ cfg.deployment_name = d3.name;
11870
+ cfg.org_id = d3.org_id;
11871
+ cfg.space_id = d3.space_id;
11872
+ cfg.mode = undefined;
11873
+ saveConfig(cfg);
11874
+ emitStep({
11875
+ step: "deployment",
11876
+ deployment_id: d3.deployment_id,
11877
+ name: d3.name
11878
+ });
11879
+ return { code: 0, cfg };
11880
+ } catch (err) {
11881
+ emitError({
11882
+ step: "deployment",
11883
+ reason: "fetch_failed",
11884
+ agent_next_steps: `Failed to load deployments: ${err instanceof Error ? err.message : String(err)}.`
11885
+ });
11886
+ return { code: 1, cfg };
11887
+ }
11888
+ }
11889
+ if (cfg.deployment_id) {
11890
+ emitStep({
11891
+ step: "deployment",
11892
+ deployment_id: cfg.deployment_id,
11893
+ name: cfg.deployment_name
11894
+ });
11895
+ return { code: 0, cfg };
11896
+ }
11897
+ try {
11898
+ const deployments = await client.getDeployments();
11899
+ if (deployments.length === 0) {
11900
+ emitError({
11901
+ step: "deployment",
11902
+ reason: "no_deployments",
11903
+ agent_next_steps: "No Dosu deployments are accessible to this account. Tell the user to create one at https://app.dosu.dev before retrying."
11904
+ });
11905
+ return { code: 1, cfg };
11906
+ }
11907
+ if (deployments.length === 1) {
11908
+ const d3 = deployments[0];
11909
+ cfg.deployment_id = d3.deployment_id;
11910
+ cfg.deployment_name = d3.name;
11911
+ cfg.org_id = d3.org_id;
11912
+ cfg.space_id = d3.space_id;
11913
+ cfg.mode = undefined;
11914
+ saveConfig(cfg);
11915
+ emitStep({
11916
+ step: "deployment",
11917
+ deployment_id: d3.deployment_id,
11918
+ name: d3.name
11919
+ });
11920
+ return { code: 0, cfg };
11921
+ }
11922
+ emitError({
11923
+ step: "deployment",
11924
+ reason: "multiple_deployments",
11925
+ agent_next_steps: "User has multiple Dosu deployments. Ask the user which one to use, then re-run the same command with `--deployment <id>`. Run 'dosu deployments list --json' to list options."
11926
+ });
11927
+ return { code: 1, cfg };
11928
+ } catch (err) {
11929
+ emitError({
11930
+ step: "deployment",
11931
+ reason: "fetch_failed",
11932
+ agent_next_steps: `Failed to load deployments: ${err instanceof Error ? err.message : String(err)}.`
11933
+ });
11934
+ return { code: 1, cfg };
11935
+ }
11936
+ }
11937
+ async function ensureAPIKey(client, cfg) {
11938
+ if (!cfg.deployment_id) {
11939
+ emitError({
11940
+ step: "api_key",
11941
+ reason: "no_deployment",
11942
+ agent_next_steps: "Internal error: tried to mint an API key without a deployment. Re-run setup from scratch."
11943
+ });
11944
+ return { code: 1, cfg };
11945
+ }
11946
+ try {
11947
+ if (cfg.api_key) {
11948
+ const valid = await client.validateAPIKey(cfg.api_key, cfg.deployment_id);
11949
+ if (valid) {
11950
+ emitStep({ step: "api_key", reused: true });
11951
+ return { code: 0, cfg };
11952
+ }
11953
+ }
11954
+ const resp = await client.createAPIKey(cfg.deployment_id, "dosu-cli");
11955
+ cfg.api_key = resp.api_key;
11956
+ saveConfig(cfg);
11957
+ emitStep({ step: "api_key", reused: false });
11958
+ return { code: 0, cfg };
11959
+ } catch (err) {
11960
+ emitError({
11961
+ step: "api_key",
11962
+ reason: "create_failed",
11963
+ agent_next_steps: `Failed to create an API key: ${err instanceof Error ? err.message : String(err)}.`
11964
+ });
11965
+ return { code: 1, cfg };
11966
+ }
11967
+ }
11968
+ function buildResumeCommand(tool, ticket, deploymentID) {
11969
+ const parts = [NPX_INVOCATION, "setup", "--agent", "--tool", tool, "--login-ticket", ticket];
11970
+ if (deploymentID) {
11971
+ parts.push("--deployment", deploymentID);
11972
+ }
11973
+ return parts.join(" ");
11974
+ }
11975
+ function listAgentSupportedToolIDs() {
11976
+ return allSetupProviders().filter((p2) => !isStdioOnly(p2)).map((p2) => p2.id());
11977
+ }
11978
+ var NPX_INVOCATION = "npx @dosu/cli@latest";
11979
+ var init_flow3 = __esm(() => {
11980
+ init_ticket();
11981
+ init_client();
11982
+ init_config();
11983
+ init_logger();
11984
+ init_providers();
11985
+ init_flow2();
11986
+ });
11987
+
10985
11988
  // src/cli/cli.ts
10986
11989
  init_esm();
10987
11990
  import { readFileSync as readFileSync8, unlinkSync as unlinkSync2 } from "node:fs";
@@ -11266,15 +12269,17 @@ ${import_picocolors6.default.dim(`Current: ${cfg.deployment_name ?? cfg.deployme
11266
12269
  }
11267
12270
 
11268
12271
  // src/commands/docs.ts
12272
+ init_dist6();
12273
+ init_dist();
11269
12274
  init_esm();
11270
12275
  init_trpc();
11271
12276
  init_logger();
11272
- var import_picocolors7 = __toESM(require_picocolors(), 1);
12277
+ var import_picocolors8 = __toESM(require_picocolors(), 1);
11273
12278
  import { readFileSync as readFileSync3 } from "node:fs";
11274
12279
  function requireConfig4() {
11275
12280
  const cfg = requireLoginConfig();
11276
12281
  if (!cfg.space_id) {
11277
- console.error(import_picocolors7.default.red("Missing space config. Run 'dosu setup' to reconfigure."));
12282
+ console.error(import_picocolors8.default.red("Missing space config. Run 'dosu setup' to reconfigure."));
11278
12283
  process.exit(1);
11279
12284
  }
11280
12285
  return cfg;
@@ -11284,7 +12289,7 @@ async function getKnowledgeStoreId(client, spaceId) {
11284
12289
  space_id: spaceId
11285
12290
  });
11286
12291
  if (!store) {
11287
- console.error(import_picocolors7.default.red("No knowledge store found for this deployment."));
12292
+ console.error(import_picocolors8.default.red("No knowledge store found for this deployment."));
11288
12293
  process.exit(1);
11289
12294
  }
11290
12295
  return store.id;
@@ -11294,10 +12299,65 @@ function readBody(opts) {
11294
12299
  return readFileSync3(opts.bodyFile, "utf-8");
11295
12300
  return opts.body;
11296
12301
  }
12302
+ var IMPORT_ALREADY_IN_PROGRESS_CODE = "IMPORT_ALREADY_IN_PROGRESS";
12303
+ var IMPORT_ALREADY_IN_PROGRESS_LEGACY_DETAIL_PHRASE = "import operation is already in progress";
12304
+ function parseSerializedImportError(message) {
12305
+ let text = message;
12306
+ let appCode;
12307
+ try {
12308
+ const parsed = JSON.parse(message);
12309
+ let codeCandidate;
12310
+ if (typeof parsed?.detail === "string") {
12311
+ text = parsed.detail;
12312
+ codeCandidate = parsed.code ?? parsed.dosuCode;
12313
+ } else if (parsed?.detail !== null && typeof parsed.detail === "object") {
12314
+ const inner = parsed.detail;
12315
+ if (typeof inner.detail === "string") {
12316
+ text = inner.detail;
12317
+ } else if (typeof inner.message === "string") {
12318
+ text = inner.message;
12319
+ }
12320
+ codeCandidate = inner.code ?? inner.dosuCode ?? parsed.code ?? parsed.dosuCode;
12321
+ } else {
12322
+ codeCandidate = parsed.code ?? parsed.dosuCode;
12323
+ }
12324
+ if (typeof codeCandidate === "string" && codeCandidate === IMPORT_ALREADY_IN_PROGRESS_CODE) {
12325
+ appCode = IMPORT_ALREADY_IN_PROGRESS_CODE;
12326
+ }
12327
+ } catch {}
12328
+ return {
12329
+ detail: text || "Import failed. Please try again.",
12330
+ appCode
12331
+ };
12332
+ }
12333
+ function trpcImportConflictAppCode(err) {
12334
+ if (!isTRPCClientError(err))
12335
+ return;
12336
+ const { data } = err;
12337
+ if (data === null || typeof data !== "object")
12338
+ return;
12339
+ const d3 = data;
12340
+ let candidate = d3.code;
12341
+ if (typeof candidate !== "string")
12342
+ candidate = d3.dosuCode;
12343
+ if (typeof candidate !== "string")
12344
+ return;
12345
+ return candidate === IMPORT_ALREADY_IN_PROGRESS_CODE ? IMPORT_ALREADY_IN_PROGRESS_CODE : undefined;
12346
+ }
12347
+ function isConcurrentImportError(err, msg) {
12348
+ if (trpcImportConflictAppCode(err) === IMPORT_ALREADY_IN_PROGRESS_CODE) {
12349
+ return true;
12350
+ }
12351
+ const { detail, appCode } = parseSerializedImportError(msg);
12352
+ if (appCode === IMPORT_ALREADY_IN_PROGRESS_CODE) {
12353
+ return true;
12354
+ }
12355
+ return detail.includes(IMPORT_ALREADY_IN_PROGRESS_LEGACY_DETAIL_PHRASE);
12356
+ }
11297
12357
  async function backendPost(path, apiKey, body) {
11298
12358
  const backendURL = getBackendURL();
11299
12359
  if (!backendURL) {
11300
- console.error(import_picocolors7.default.red("Backend URL not configured."));
12360
+ console.error(import_picocolors8.default.red("Backend URL not configured."));
11301
12361
  process.exit(1);
11302
12362
  }
11303
12363
  const resp = await fetch(`${backendURL}${path}`, {
@@ -11333,14 +12393,14 @@ function docsCommand() {
11333
12393
  return;
11334
12394
  }
11335
12395
  if (!pages || pages.length === 0) {
11336
- console.log(import_picocolors7.default.dim("No documents found."));
12396
+ console.log(import_picocolors8.default.dim("No documents found."));
11337
12397
  return;
11338
12398
  }
11339
- printTable(["ID", "Title", "Status", "Created"], pages.map((p) => [
11340
- p.id.slice(0, 8),
11341
- truncate(p.title ?? "(untitled)", 50),
11342
- p.published ? "published" : "draft",
11343
- formatDate(p.created_at)
12399
+ printTable(["ID", "Title", "Status", "Created"], pages.map((p2) => [
12400
+ p2.id.slice(0, 8),
12401
+ truncate(p2.title ?? "(untitled)", 50),
12402
+ p2.published ? "published" : "draft",
12403
+ formatDate(p2.created_at)
11344
12404
  ]), { rawData: pages });
11345
12405
  });
11346
12406
  cmd.command("get").description("Get a document").argument("<id>", "Page ID").option("--version <v>", "Specific version number").option("--json", "Output as JSON").action(async (id, opts) => {
@@ -11355,10 +12415,10 @@ function docsCommand() {
11355
12415
  return;
11356
12416
  }
11357
12417
  if (!page) {
11358
- console.log(import_picocolors7.default.dim("Document not found."));
12418
+ console.log(import_picocolors8.default.dim("Document not found."));
11359
12419
  return;
11360
12420
  }
11361
- console.log(import_picocolors7.default.bold(page.title ?? "(untitled)"));
12421
+ console.log(import_picocolors8.default.bold(page.title ?? "(untitled)"));
11362
12422
  printInfo([
11363
12423
  ["ID", page.id],
11364
12424
  ["Status", page.published ? "published" : "draft"],
@@ -11383,7 +12443,7 @@ ${page.body}`);
11383
12443
  printResult(result, opts);
11384
12444
  return;
11385
12445
  }
11386
- console.log(import_picocolors7.default.green(`Document "${opts.title}" created.`));
12446
+ console.log(import_picocolors8.default.green(`Document "${opts.title}" created.`));
11387
12447
  });
11388
12448
  cmd.command("update").description("Update a document").argument("<id>", "Page ID").option("--title <title>", "New title").option("--body <markdown>", "New body (markdown)").option("--body-file <path>", "Read body from file").option("--json", "Output as JSON").action(async (id, opts) => {
11389
12449
  const cfg = requireConfig4();
@@ -11400,7 +12460,7 @@ ${page.body}`);
11400
12460
  printResult(result, opts);
11401
12461
  return;
11402
12462
  }
11403
- console.log(import_picocolors7.default.green("Document updated."));
12463
+ console.log(import_picocolors8.default.green("Document updated."));
11404
12464
  });
11405
12465
  for (const archived of [true, false]) {
11406
12466
  const name = archived ? "archive" : "unarchive";
@@ -11412,7 +12472,7 @@ ${page.body}`);
11412
12472
  printResult({ success: true, id, archived }, opts);
11413
12473
  return;
11414
12474
  }
11415
- console.log(import_picocolors7.default.green(`Document ${name}d.`));
12475
+ console.log(import_picocolors8.default.green(`Document ${name}d.`));
11416
12476
  });
11417
12477
  }
11418
12478
  cmd.command("delete").description("Delete a document").argument("<id>", "Page ID").option("--json", "Output as JSON").action(async (id, opts) => {
@@ -11423,7 +12483,7 @@ ${page.body}`);
11423
12483
  printResult({ success: true, id }, opts);
11424
12484
  return;
11425
12485
  }
11426
- console.log(import_picocolors7.default.green("Document deleted."));
12486
+ console.log(import_picocolors8.default.green("Document deleted."));
11427
12487
  });
11428
12488
  cmd.command("versions").description("List document versions").argument("<id>", "Page ID").option("--json", "Output as JSON").action(async (id, opts) => {
11429
12489
  const cfg = requireConfig4();
@@ -11434,7 +12494,7 @@ ${page.body}`);
11434
12494
  return;
11435
12495
  }
11436
12496
  if (!versions || versions.length === 0) {
11437
- console.log(import_picocolors7.default.dim("No versions found."));
12497
+ console.log(import_picocolors8.default.dim("No versions found."));
11438
12498
  return;
11439
12499
  }
11440
12500
  printTable(["Version", "Created"], versions.map((v) => [
@@ -11453,7 +12513,7 @@ ${page.body}`);
11453
12513
  printResult({ success: true, id, version: opts.version }, opts);
11454
12514
  return;
11455
12515
  }
11456
- console.log(import_picocolors7.default.green(`Document restored to version ${opts.version}.`));
12516
+ console.log(import_picocolors8.default.green(`Document restored to version ${opts.version}.`));
11457
12517
  });
11458
12518
  cmd.command("generate").description("Generate a document using AI").requiredOption("--title <title>", "Document title").option("--instructions <text>", "Custom generation instructions").option("--json", "Output as JSON").action(async (opts) => {
11459
12519
  const cfg = requireConfig4();
@@ -11468,7 +12528,7 @@ ${page.body}`);
11468
12528
  printResult(result, opts);
11469
12529
  return;
11470
12530
  }
11471
- console.log(import_picocolors7.default.green("Document generation started."));
12531
+ console.log(import_picocolors8.default.green("Document generation started."));
11472
12532
  });
11473
12533
  cmd.command("auto-tag").description("Auto-tag a document using AI").argument("<id>", "Page ID").option("--json", "Output as JSON").action(async (id, opts) => {
11474
12534
  const cfg = requireConfig4();
@@ -11477,7 +12537,7 @@ ${page.body}`);
11477
12537
  printResult(result, opts);
11478
12538
  return;
11479
12539
  }
11480
- console.log(import_picocolors7.default.green("Auto-tagging started."));
12540
+ console.log(import_picocolors8.default.green("Auto-tagging started."));
11481
12541
  });
11482
12542
  cmd.command("import").description("Import documents from an external platform").argument("<platform>", "Platform: github, gitlab, confluence, notion, coda").requiredOption("--files <ids>", "Comma-separated file/page IDs to import").option("--json", "Output as JSON").action(async (platform, opts) => {
11483
12543
  const cfg = requireConfig4();
@@ -11493,20 +12553,38 @@ ${page.body}`);
11493
12553
  };
11494
12554
  const fn = importFn[platform.toLowerCase()];
11495
12555
  if (!fn) {
11496
- console.error(import_picocolors7.default.red(`Unknown platform: ${platform}. Use: github, gitlab, confluence, notion, coda`));
12556
+ console.error(import_picocolors8.default.red(`Unknown platform: ${platform}. Use: github, gitlab, confluence, notion, coda`));
11497
12557
  process.exit(1);
11498
12558
  }
11499
12559
  const idField = ["confluence", "notion", "coda"].includes(platform.toLowerCase()) ? "page_ids" : "file_ids";
11500
- const result = await fn({
11501
- knowledge_store_id: ksId,
11502
- space_id: cfg.space_id,
11503
- [idField]: fileIds
11504
- });
11505
- if (opts.json) {
11506
- printResult(result, opts);
11507
- return;
12560
+ try {
12561
+ const result = await fn({
12562
+ knowledge_store_id: ksId,
12563
+ space_id: cfg.space_id,
12564
+ [idField]: fileIds
12565
+ });
12566
+ if (opts.json) {
12567
+ printResult(result, opts);
12568
+ return;
12569
+ }
12570
+ console.log(import_picocolors8.default.green(`Import started.${result.task_id ? ` Task ID: ${result.task_id}` : ""}`));
12571
+ } catch (err) {
12572
+ const msg = err instanceof Error ? err.message : String(err);
12573
+ logger.warn("docs-import", `Import failed: ${msg}`);
12574
+ const { detail } = parseSerializedImportError(msg);
12575
+ const isConcurrentImport = isConcurrentImportError(err, msg);
12576
+ if (opts.json) {
12577
+ const error = isConcurrentImport ? "An import is already in progress for this organization. Wait for it to complete or check status with: dosu docs import-status <task-id>" : detail;
12578
+ console.error(JSON.stringify({ error }));
12579
+ } else if (isConcurrentImport) {
12580
+ M2.error("An import is already in progress for this organization.");
12581
+ M2.info(`Check status with: ${import_picocolors8.default.cyan("dosu docs import-status <task-id>")}`);
12582
+ M2.info("Only one import can run per organization at a time.");
12583
+ } else {
12584
+ M2.error(detail);
12585
+ }
12586
+ process.exit(1);
11508
12587
  }
11509
- console.log(import_picocolors7.default.green(`Import started.${result.task_id ? ` Task ID: ${result.task_id}` : ""}`));
11510
12588
  });
11511
12589
  cmd.command("import-status").description("Check import task status").argument("<task-id>", "Import task ID").option("--json", "Output as JSON").action(async (taskId, opts) => {
11512
12590
  const cfg = requireConfig4();
@@ -11517,7 +12595,7 @@ ${page.body}`);
11517
12595
  return;
11518
12596
  }
11519
12597
  if (!status) {
11520
- console.log(import_picocolors7.default.dim("Import task not found."));
12598
+ console.log(import_picocolors8.default.dim("Import task not found."));
11521
12599
  return;
11522
12600
  }
11523
12601
  console.log(`Status: ${JSON.stringify(status)}`);
@@ -11566,7 +12644,7 @@ ${page.body}`);
11566
12644
  };
11567
12645
  const config = publishMap[platform];
11568
12646
  if (!config) {
11569
- console.error(import_picocolors7.default.red(`Unknown platform: ${platform}`));
12647
+ console.error(import_picocolors8.default.red(`Unknown platform: ${platform}`));
11570
12648
  process.exit(1);
11571
12649
  }
11572
12650
  logger.debug("docs", `Publishing to ${platform}`);
@@ -11575,7 +12653,7 @@ ${page.body}`);
11575
12653
  printResult(result, opts);
11576
12654
  return;
11577
12655
  }
11578
- console.log(import_picocolors7.default.green(`Document published to ${platform}.`));
12656
+ console.log(import_picocolors8.default.green(`Document published to ${platform}.`));
11579
12657
  });
11580
12658
  cmd.command("sync-back").description("Sync document back to its source (Notion/Confluence)").argument("<id>", "Page ID").option("--json", "Output as JSON").action(async (id, opts) => {
11581
12659
  const cfg = requireConfig4();
@@ -11585,7 +12663,7 @@ ${page.body}`);
11585
12663
  printResult(result, opts);
11586
12664
  return;
11587
12665
  }
11588
- console.log(import_picocolors7.default.green("Sync-back initiated."));
12666
+ console.log(import_picocolors8.default.green("Sync-back initiated."));
11589
12667
  });
11590
12668
  return cmd;
11591
12669
  }
@@ -12528,7 +13606,25 @@ function createProgram() {
12528
13606
  const { runTUI: runTUI2 } = await Promise.resolve().then(() => (init_tui(), exports_tui));
12529
13607
  await runTUI2();
12530
13608
  });
12531
- program2.command("login").description("Authenticate with Dosu via OAuth").action(async () => {
13609
+ program2.command("login").description("Authenticate with Dosu via OAuth").option("--request", "Mint a login ticket for agent / human-in-the-loop auth (prints URL and exits)").option("--check <ticket>", "Exchange a login ticket created with --request for a token").option("--json", "Emit machine-readable JSON output (use with --request or --check)").action(async (opts) => {
13610
+ if (opts.request && opts.check !== undefined) {
13611
+ console.error("--request and --check cannot be combined.");
13612
+ process.exitCode = 2;
13613
+ return;
13614
+ }
13615
+ if (opts.request) {
13616
+ const { runLoginRequest: runLoginRequest2 } = await Promise.resolve().then(() => (init_login_commands(), exports_login_commands));
13617
+ process.exitCode = await runLoginRequest2({ json: opts.json === true });
13618
+ return;
13619
+ }
13620
+ if (opts.check !== undefined) {
13621
+ const { runLoginCheck: runLoginCheck2 } = await Promise.resolve().then(() => (init_login_commands(), exports_login_commands));
13622
+ process.exitCode = await runLoginCheck2({
13623
+ ticket: opts.check,
13624
+ json: opts.json === true
13625
+ });
13626
+ return;
13627
+ }
12532
13628
  const cfg = loadConfig();
12533
13629
  if (isAuthenticated(cfg) && !isTokenExpired(cfg)) {
12534
13630
  console.log("You are already logged in.");
@@ -12594,7 +13690,7 @@ function createProgram() {
12594
13690
  console.log(`MCP ID: ${cfg.deployment_id}`);
12595
13691
  } else {
12596
13692
  console.log("MCP: None selected");
12597
- console.log("Run 'dosu' to open the TUI and select an MCP.");
13693
+ console.log("Run 'dosu deployments list' to see available MCPs, then 'dosu deployments switch <id>' to select one.");
12598
13694
  }
12599
13695
  });
12600
13696
  const mcp = program2.command("mcp").description("Manage MCP server integrations");
@@ -12670,7 +13766,30 @@ Use 'dosu mcp add <agent>' to add Dosu MCP to a tool.`);
12670
13766
  program2.addCommand(tagsCommand());
12671
13767
  program2.addCommand(threadsCommand());
12672
13768
  program2.addCommand(skillCommand());
12673
- program2.command("setup").description("Set up Dosu MCP for your AI tools").option("--deployment <id>", "Skip to tool configuration for a specific MCP").option("--mode <mode>", "Force OSS or Cloud mode, skipping the interactive prompt (oss|cloud)").action(async (opts) => {
13769
+ program2.command("setup").description("Set up Dosu MCP for your AI tools").option("--deployment <id>", "Skip to tool configuration for a specific MCP").option("--mode <mode>", "Force OSS or Cloud mode, skipping the interactive prompt (oss|cloud)").option("--agent", "Run non-interactive setup designed for coding agents (requires --tool)").option("--tool <id>", "Configure a single AI tool by id (claude, cursor, codex, …). Required with --agent.").option("--login-ticket <ticket>", "Resume an --agent setup by redeeming a ticket from a previous run").action(async (opts) => {
13770
+ if (opts.agent) {
13771
+ if (!opts.tool) {
13772
+ const { emitError: emitError2 } = await Promise.resolve().then(() => exports_output);
13773
+ const { listAgentSupportedToolIDs: listAgentSupportedToolIDs2 } = await Promise.resolve().then(() => (init_flow3(), exports_flow3));
13774
+ emitError2({
13775
+ step: "setup",
13776
+ reason: "missing_tool",
13777
+ agent_next_steps: `Pass --tool <id> when using --agent. Supported ids: ${listAgentSupportedToolIDs2().join(", ")}.`
13778
+ });
13779
+ process.exitCode = 2;
13780
+ return;
13781
+ }
13782
+ const { runAgentSetup: runAgentSetup2 } = await Promise.resolve().then(() => (init_flow3(), exports_flow3));
13783
+ process.exitCode = await runAgentSetup2({
13784
+ tool: opts.tool,
13785
+ loginTicket: opts.loginTicket,
13786
+ deploymentID: opts.deployment
13787
+ });
13788
+ return;
13789
+ }
13790
+ if (opts.tool || opts.loginTicket) {
13791
+ throw new Error("--tool and --login-ticket require --agent");
13792
+ }
12674
13793
  const { runSetup: runSetup2 } = await Promise.resolve().then(() => (init_flow2(), exports_flow2));
12675
13794
  let mode;
12676
13795
  if (opts.mode !== undefined) {