@dosu/cli 0.24.0 → 0.26.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 +116 -15
  2. package/package.json +1 -1
package/bin/dosu.js CHANGED
@@ -4577,7 +4577,7 @@ var init_dist4 = __esm(() => {
4577
4577
  function getVersionString() {
4578
4578
  return `v${VERSION}`;
4579
4579
  }
4580
- var VERSION = "0.24.0", INSTALL_CHANNEL = "npm";
4580
+ var VERSION = "0.26.0", INSTALL_CHANNEL = "npm";
4581
4581
 
4582
4582
  // src/debug/logger.ts
4583
4583
  import {
@@ -13657,7 +13657,7 @@ var init_flow3 = __esm(() => {
13657
13657
  // src/cli/cli.ts
13658
13658
  init_commander();
13659
13659
  init_client();
13660
- import { readFileSync as readFileSync13, unlinkSync as unlinkSync2 } from "node:fs";
13660
+ import { readFileSync as readFileSync14, unlinkSync as unlinkSync2 } from "node:fs";
13661
13661
 
13662
13662
  // src/commands/analytics.ts
13663
13663
  init_commander();
@@ -15253,10 +15253,12 @@ ${import_picocolors17.default.dim(`Current: ${cfg.org_id}`)}`);
15253
15253
  }
15254
15254
 
15255
15255
  // src/commands/review.ts
15256
+ init_dist8();
15256
15257
  init_dist();
15257
15258
  init_commander();
15258
15259
  init_trpc();
15259
15260
  var import_picocolors18 = __toESM(require_picocolors(), 1);
15261
+ import { readFileSync as readFileSync12 } from "node:fs";
15260
15262
  function requireConfig9() {
15261
15263
  return requireLoginConfig();
15262
15264
  }
@@ -15274,6 +15276,35 @@ function humanizeSource(origin, version) {
15274
15276
  return origin;
15275
15277
  }
15276
15278
  }
15279
+ function colorizeDiff(diff) {
15280
+ return diff.split(`
15281
+ `).map((line) => {
15282
+ if (line.startsWith("+"))
15283
+ return import_picocolors18.default.green(line);
15284
+ if (line.startsWith("-"))
15285
+ return import_picocolors18.default.red(line);
15286
+ if (line.startsWith("@@"))
15287
+ return import_picocolors18.default.cyan(line);
15288
+ return import_picocolors18.default.dim(line);
15289
+ }).join(`
15290
+ `);
15291
+ }
15292
+ function printChangePreview(change) {
15293
+ printInfo([
15294
+ ["Title", change.title],
15295
+ ["Source", change.source],
15296
+ [
15297
+ "Version",
15298
+ change.isNewDoc ? `${change.version} (new)` : `${change.publishedVersion ?? "?"} → ${change.version}`
15299
+ ]
15300
+ ]);
15301
+ if (!change.hasChanges) {
15302
+ console.log(import_picocolors18.default.dim("No content changes."));
15303
+ return;
15304
+ }
15305
+ console.log();
15306
+ console.log(colorizeDiff(change.diff));
15307
+ }
15277
15308
  async function getKnowledgeStoreId2(client, spaceId) {
15278
15309
  const store = await client.knowledgeStore.getBySpaceId.query({ space_id: spaceId });
15279
15310
  if (!store) {
@@ -15333,6 +15364,45 @@ function reviewCommand() {
15333
15364
  console.log("");
15334
15365
  console.log(change.diff);
15335
15366
  });
15367
+ cmd.command("edit").description("Edit a pending document version's body/title in place").argument("<page-version-id>", "Page version ID (from `dosu review list`)").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) => {
15368
+ const cfg = requireConfig9();
15369
+ const client = createTypedClient(cfg);
15370
+ if (opts.body !== undefined && opts.bodyFile !== undefined) {
15371
+ console.error(import_picocolors18.default.red("Pass only one of --body or --body-file."));
15372
+ process.exit(1);
15373
+ }
15374
+ let body = opts.body;
15375
+ if (opts.bodyFile) {
15376
+ try {
15377
+ body = readFileSync12(opts.bodyFile, "utf-8");
15378
+ } catch (err) {
15379
+ console.error(import_picocolors18.default.red(`Failed to read --body-file: ${err.message}`));
15380
+ process.exit(1);
15381
+ }
15382
+ }
15383
+ if (body === undefined && opts.title === undefined) {
15384
+ console.error(import_picocolors18.default.red("Nothing to edit. Pass --title and/or --body/--body-file."));
15385
+ process.exit(1);
15386
+ }
15387
+ try {
15388
+ await client.page.updateReview.mutate({
15389
+ page_version_id: id,
15390
+ title: opts.title,
15391
+ body
15392
+ });
15393
+ } catch (err) {
15394
+ if (isTRPCClientError(err) && err.data?.code === "NOT_FOUND") {
15395
+ console.error(import_picocolors18.default.red(`No pending review item found for '${id}'. Run 'dosu review list' to see editable items.`));
15396
+ process.exit(1);
15397
+ }
15398
+ throw err;
15399
+ }
15400
+ if (opts.json) {
15401
+ printResult({ success: true, id }, opts);
15402
+ return;
15403
+ }
15404
+ console.log(import_picocolors18.default.green(`Review edited: ${id.slice(0, 8)}`));
15405
+ });
15336
15406
  cmd.command("context").description("Get review context for a thread").argument("<thread-id>", "Thread ID").option("--json", "Output as JSON").action(async (threadId, opts) => {
15337
15407
  const cfg = requireConfig9();
15338
15408
  const client = createTypedClient(cfg);
@@ -15354,19 +15424,37 @@ function reviewCommand() {
15354
15424
  ["Sync PR", ctx.syncPrUrl ?? undefined]
15355
15425
  ]);
15356
15426
  });
15357
- const actions = [
15358
- { name: "approve", action: "accept", description: "Approve a document version" },
15359
- { name: "reject", action: "decline", description: "Reject a document version" },
15360
- {
15361
- name: "revert",
15362
- action: "revert_to_pending",
15363
- description: "Revert to pending review"
15364
- }
15427
+ const gated = [
15428
+ { name: "approve", action: "accept", verb: "Approve" },
15429
+ { name: "reject", action: "decline", verb: "Reject" }
15365
15430
  ];
15366
- for (const { name, action, description } of actions) {
15367
- cmd.command(name).description(description).argument("<id>", "Review item ID (from `dosu review list`)").option("--json", "Output as JSON").action(async (id, opts) => {
15431
+ for (const { name, action, verb } of gated) {
15432
+ cmd.command(name).description(`${verb} a document version (shows the diff, requires --confirm)`).argument("<id>", "Review item ID (from `dosu review list`)").option("--confirm", "Apply without the interactive prompt").option("--json", "Output as JSON").action(async (id, opts) => {
15368
15433
  const cfg = requireConfig9();
15369
15434
  const client = createTypedClient(cfg);
15435
+ const change = await client.review.getChange.query({ id });
15436
+ if (!opts.json)
15437
+ printChangePreview(change);
15438
+ let proceed = opts.confirm === true;
15439
+ if (!proceed && !opts.json && process.stdin?.isTTY) {
15440
+ const answer = await confirm({
15441
+ message: `${verb} this change?`,
15442
+ initialValue: false
15443
+ });
15444
+ if (isCancel(answer)) {
15445
+ console.log(import_picocolors18.default.dim("Cancelled."));
15446
+ return;
15447
+ }
15448
+ proceed = answer === true;
15449
+ }
15450
+ if (!proceed) {
15451
+ if (opts.json) {
15452
+ printResult({ ...change, applied: false, confirmRequired: true }, opts);
15453
+ } else {
15454
+ console.log(import_picocolors18.default.dim("Aborted. Re-run with --confirm to apply."));
15455
+ }
15456
+ return;
15457
+ }
15370
15458
  await client.page.updatePublicationStatus.mutate({
15371
15459
  page_version_id: id,
15372
15460
  action
@@ -15378,6 +15466,19 @@ function reviewCommand() {
15378
15466
  console.log(import_picocolors18.default.green(`Review ${name}: ${id.slice(0, 8)}`));
15379
15467
  });
15380
15468
  }
15469
+ cmd.command("revert").description("Revert to pending review").argument("<id>", "Review item ID (from `dosu review list`)").option("--json", "Output as JSON").action(async (id, opts) => {
15470
+ const cfg = requireConfig9();
15471
+ const client = createTypedClient(cfg);
15472
+ await client.page.updatePublicationStatus.mutate({
15473
+ page_version_id: id,
15474
+ action: "revert_to_pending"
15475
+ });
15476
+ if (opts.json) {
15477
+ printResult({ success: true, id, action: "revert_to_pending" }, opts);
15478
+ return;
15479
+ }
15480
+ console.log(import_picocolors18.default.green(`Review revert: ${id.slice(0, 8)}`));
15481
+ });
15381
15482
  return cmd;
15382
15483
  }
15383
15484
 
@@ -15749,7 +15850,7 @@ init_skill_update_check();
15749
15850
  init_config();
15750
15851
  init_logger();
15751
15852
  var import_picocolors23 = __toESM(require_picocolors(), 1);
15752
- import { existsSync as existsSync14, mkdirSync as mkdirSync7, readFileSync as readFileSync12, writeFileSync as writeFileSync6 } from "node:fs";
15853
+ import { existsSync as existsSync14, mkdirSync as mkdirSync7, readFileSync as readFileSync13, writeFileSync as writeFileSync6 } from "node:fs";
15753
15854
  import { join as join25 } from "node:path";
15754
15855
  var CACHE_FILENAME2 = "update-check.json";
15755
15856
  var CHECK_INTERVAL_MS2 = 24 * 60 * 60 * 1000;
@@ -15780,7 +15881,7 @@ function readCache() {
15780
15881
  const path3 = getCachePath2();
15781
15882
  if (!existsSync14(path3))
15782
15883
  return null;
15783
- const data = JSON.parse(readFileSync12(path3, "utf-8"));
15884
+ const data = JSON.parse(readFileSync13(path3, "utf-8"));
15784
15885
  if (typeof data.lastCheck === "number" && typeof data.latestVersion === "string") {
15785
15886
  return data;
15786
15887
  }
@@ -16116,7 +16217,7 @@ Use 'dosu mcp add <agent>' to add Dosu MCP to a tool.`);
16116
16217
  if (opts.tail !== undefined) {
16117
16218
  const n2 = typeof opts.tail === "string" ? parseInt(opts.tail, 10) || 50 : 50;
16118
16219
  try {
16119
- const content = readFileSync13(logPath, "utf-8");
16220
+ const content = readFileSync14(logPath, "utf-8");
16120
16221
  const lines = content.split(`
16121
16222
  `);
16122
16223
  console.log(lines.slice(-n2).join(`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dosu/cli",
3
- "version": "0.24.0",
3
+ "version": "0.26.0",
4
4
  "type": "module",
5
5
  "description": "Dosu CLI - Manage MCP servers for AI tools",
6
6
  "license": "MIT",