@dosu/cli 0.26.0 → 0.27.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 +108 -36
  2. package/package.json +2 -2
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.26.0", INSTALL_CHANNEL = "npm";
4580
+ var VERSION = "0.27.0", INSTALL_CHANNEL = "npm";
4581
4581
 
4582
4582
  // src/debug/logger.ts
4583
4583
  import {
@@ -15262,6 +15262,26 @@ import { readFileSync as readFileSync12 } from "node:fs";
15262
15262
  function requireConfig9() {
15263
15263
  return requireLoginConfig();
15264
15264
  }
15265
+ function isNotFound(err) {
15266
+ return isTRPCClientError(err) && err.data?.code === "NOT_FOUND";
15267
+ }
15268
+ async function resolveChange(client, id) {
15269
+ try {
15270
+ return await client.review.getChange.query({ id });
15271
+ } catch (err) {
15272
+ if (isNotFound(err))
15273
+ return null;
15274
+ throw err;
15275
+ }
15276
+ }
15277
+ async function requireDraft(client, id) {
15278
+ const draft = await client.messages.getMessage.query(id);
15279
+ if (!draft) {
15280
+ console.error(import_picocolors18.default.red(`No review item found for '${id}'. Run 'dosu review list' to see pending items.`));
15281
+ process.exit(1);
15282
+ }
15283
+ return draft;
15284
+ }
15265
15285
  function humanizeSource(origin, version) {
15266
15286
  switch (origin) {
15267
15287
  case "manual_update":
@@ -15305,6 +15325,14 @@ function printChangePreview(change) {
15305
15325
  console.log();
15306
15326
  console.log(colorizeDiff(change.diff));
15307
15327
  }
15328
+ function printDraftPreview(draft) {
15329
+ printInfo([
15330
+ ["Title", draft.title ?? "(untitled)"],
15331
+ ["Source", "Draft reply"]
15332
+ ]);
15333
+ console.log();
15334
+ console.log(draft.body ?? "");
15335
+ }
15308
15336
  async function getKnowledgeStoreId2(client, spaceId) {
15309
15337
  const store = await client.knowledgeStore.getBySpaceId.query({ space_id: spaceId });
15310
15338
  if (!store) {
@@ -15314,8 +15342,8 @@ async function getKnowledgeStoreId2(client, spaceId) {
15314
15342
  return store.id;
15315
15343
  }
15316
15344
  function reviewCommand() {
15317
- const cmd = new Command("review").description("Document review workflow");
15318
- cmd.command("list").description("List pending document review items").option("--json", "Output as JSON").action(async (opts) => {
15345
+ const cmd = new Command("review").description("Review workflow (doc changes and draft replies)");
15346
+ cmd.command("list").description("List pending review items (doc changes and draft replies)").option("--json", "Output as JSON").action(async (opts) => {
15319
15347
  const cfg = requireConfig9();
15320
15348
  if (!cfg.space_id) {
15321
15349
  console.error(import_picocolors18.default.red("Missing space config. Run 'dosu setup' to reconfigure."));
@@ -15323,7 +15351,10 @@ function reviewCommand() {
15323
15351
  }
15324
15352
  const client = createTypedClient(cfg);
15325
15353
  const ksId = await getKnowledgeStoreId2(client, cfg.space_id);
15326
- const items = await client.review.listPending.query({ knowledgeStoreId: ksId });
15354
+ const items = await client.review.listPending.query({
15355
+ knowledgeStoreId: ksId,
15356
+ deploymentId: cfg.deployment_id
15357
+ });
15327
15358
  if (opts.json) {
15328
15359
  printResult(items, opts);
15329
15360
  return;
@@ -15332,7 +15363,14 @@ function reviewCommand() {
15332
15363
  console.log(import_picocolors18.default.dim("No pending review items."));
15333
15364
  return;
15334
15365
  }
15335
- printTable(["ID", "Kind", "Title", "Source", "Status", "Created"], items.map((i2) => [
15366
+ printTable(["ID", "Kind", "Title", "Source", "Status", "Created"], items.map((i2) => i2.kind === "draft_message" ? [
15367
+ i2.id.slice(0, 8),
15368
+ i2.kind,
15369
+ truncate(i2.title || "(untitled)", 40),
15370
+ "Draft reply",
15371
+ "draft",
15372
+ formatDate(i2.createdAt)
15373
+ ] : [
15336
15374
  i2.id.slice(0, 8),
15337
15375
  i2.kind,
15338
15376
  truncate(i2.title ?? "(untitled)", 40),
@@ -15341,18 +15379,21 @@ function reviewCommand() {
15341
15379
  formatDate(i2.createdAt)
15342
15380
  ]), { rawData: items });
15343
15381
  });
15344
- cmd.command("diff").description("Show the server-rendered diff for a pending document version").argument("<page-version-id>", "Page version ID (from `dosu review list`)").option("--json", "Output as JSON").action(async (id, opts) => {
15382
+ cmd.command("diff").description("Show a pending review item (doc-change diff or draft reply body)").argument("<id>", "Review item ID (from `dosu review list`)").option("--json", "Output as JSON").action(async (id, opts) => {
15345
15383
  const cfg = requireConfig9();
15346
15384
  const client = createTypedClient(cfg);
15347
- let change;
15348
- try {
15349
- change = await client.review.getChange.query({ id });
15350
- } catch (err) {
15351
- if (isTRPCClientError(err) && err.data?.code === "NOT_FOUND") {
15352
- console.error(import_picocolors18.default.red(`No review item found for '${id}'. Run 'dosu review list' to see pending items.`));
15353
- process.exit(1);
15385
+ const change = await resolveChange(client, id);
15386
+ if (!change) {
15387
+ const draft = await requireDraft(client, id);
15388
+ if (opts.json) {
15389
+ printResult({ id, kind: "draft_message", title: draft.title, body: draft.body }, opts);
15390
+ return;
15354
15391
  }
15355
- throw err;
15392
+ console.log(import_picocolors18.default.bold(draft.title ?? "(untitled)"));
15393
+ console.log(import_picocolors18.default.dim("Draft reply"));
15394
+ console.log("");
15395
+ console.log(draft.body ?? "");
15396
+ return;
15356
15397
  }
15357
15398
  if (opts.json) {
15358
15399
  printResult(change, opts);
@@ -15364,7 +15405,7 @@ function reviewCommand() {
15364
15405
  console.log("");
15365
15406
  console.log(change.diff);
15366
15407
  });
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) => {
15408
+ cmd.command("edit").description("Edit a pending review item in place (doc body/title, or draft reply body)").argument("<id>", "Review item 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
15409
  const cfg = requireConfig9();
15369
15410
  const client = createTypedClient(cfg);
15370
15411
  if (opts.body !== undefined && opts.bodyFile !== undefined) {
@@ -15384,18 +15425,28 @@ function reviewCommand() {
15384
15425
  console.error(import_picocolors18.default.red("Nothing to edit. Pass --title and/or --body/--body-file."));
15385
15426
  process.exit(1);
15386
15427
  }
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.`));
15428
+ const change = await resolveChange(client, id);
15429
+ if (!change) {
15430
+ if (opts.title !== undefined) {
15431
+ console.error(import_picocolors18.default.red("Draft replies support --body only (no --title)."));
15396
15432
  process.exit(1);
15397
15433
  }
15398
- throw err;
15434
+ await requireDraft(client, id);
15435
+ await client.messages.saveDraft.mutate({ messageId: id, body });
15436
+ } else {
15437
+ try {
15438
+ await client.page.updateReview.mutate({
15439
+ page_version_id: id,
15440
+ title: opts.title,
15441
+ body
15442
+ });
15443
+ } catch (err) {
15444
+ if (isNotFound(err)) {
15445
+ console.error(import_picocolors18.default.red(`No pending review item found for '${id}'. Run 'dosu review list' to see editable items.`));
15446
+ process.exit(1);
15447
+ }
15448
+ throw err;
15449
+ }
15399
15450
  }
15400
15451
  if (opts.json) {
15401
15452
  printResult({ success: true, id }, opts);
@@ -15429,16 +15480,22 @@ function reviewCommand() {
15429
15480
  { name: "reject", action: "decline", verb: "Reject" }
15430
15481
  ];
15431
15482
  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) => {
15483
+ cmd.command(name).description(`${verb} a review item (doc change or draft reply; shows a preview, 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) => {
15433
15484
  const cfg = requireConfig9();
15434
15485
  const client = createTypedClient(cfg);
15435
- const change = await client.review.getChange.query({ id });
15436
- if (!opts.json)
15437
- printChangePreview(change);
15486
+ const change = await resolveChange(client, id);
15487
+ const draft = change ? null : await requireDraft(client, id);
15488
+ const noun = change ? "change" : "draft reply";
15489
+ if (!opts.json) {
15490
+ if (change)
15491
+ printChangePreview(change);
15492
+ else
15493
+ printDraftPreview(draft);
15494
+ }
15438
15495
  let proceed = opts.confirm === true;
15439
15496
  if (!proceed && !opts.json && process.stdin?.isTTY) {
15440
15497
  const answer = await confirm({
15441
- message: `${verb} this change?`,
15498
+ message: `${verb} this ${noun}?`,
15442
15499
  initialValue: false
15443
15500
  });
15444
15501
  if (isCancel(answer)) {
@@ -15449,16 +15506,25 @@ function reviewCommand() {
15449
15506
  }
15450
15507
  if (!proceed) {
15451
15508
  if (opts.json) {
15452
- printResult({ ...change, applied: false, confirmRequired: true }, opts);
15509
+ const preview = change ?? {
15510
+ id,
15511
+ kind: "draft_message",
15512
+ title: draft?.title,
15513
+ body: draft?.body
15514
+ };
15515
+ printResult({ ...preview, applied: false, confirmRequired: true }, opts);
15453
15516
  } else {
15454
15517
  console.log(import_picocolors18.default.dim("Aborted. Re-run with --confirm to apply."));
15455
15518
  }
15456
15519
  return;
15457
15520
  }
15458
- await client.page.updatePublicationStatus.mutate({
15459
- page_version_id: id,
15460
- action
15461
- });
15521
+ if (change) {
15522
+ await client.page.updatePublicationStatus.mutate({ page_version_id: id, action });
15523
+ } else if (action === "accept") {
15524
+ await client.messages.publishMessage.mutate({ postId: id });
15525
+ } else {
15526
+ await client.messages.deleteMessage.mutate(id);
15527
+ }
15462
15528
  if (opts.json) {
15463
15529
  printResult({ success: true, id, action }, opts);
15464
15530
  return;
@@ -15466,9 +15532,15 @@ function reviewCommand() {
15466
15532
  console.log(import_picocolors18.default.green(`Review ${name}: ${id.slice(0, 8)}`));
15467
15533
  });
15468
15534
  }
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) => {
15535
+ cmd.command("revert").description("Revert a doc change to pending review (not supported for draft replies)").argument("<id>", "Review item ID (from `dosu review list`)").option("--json", "Output as JSON").action(async (id, opts) => {
15470
15536
  const cfg = requireConfig9();
15471
15537
  const client = createTypedClient(cfg);
15538
+ const change = await resolveChange(client, id);
15539
+ if (!change) {
15540
+ await requireDraft(client, id);
15541
+ console.error(import_picocolors18.default.red("Revert is not supported for draft replies. A rejected draft is regenerated on the next agent run."));
15542
+ process.exit(1);
15543
+ }
15472
15544
  await client.page.updatePublicationStatus.mutate({
15473
15545
  page_version_id: id,
15474
15546
  action: "revert_to_pending"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dosu/cli",
3
- "version": "0.26.0",
3
+ "version": "0.27.0",
4
4
  "type": "module",
5
5
  "description": "Dosu CLI - Manage MCP servers for AI tools",
6
6
  "license": "MIT",
@@ -37,7 +37,7 @@
37
37
  "devDependencies": {
38
38
  "@biomejs/biome": "^2.5.0",
39
39
  "@clack/prompts": "^1.6.0",
40
- "@dosu/api-types": "0.0.33",
40
+ "@dosu/api-types": "0.0.36",
41
41
  "@semantic-release/changelog": "^6.0.3",
42
42
  "@semantic-release/exec": "^7.1.0",
43
43
  "@semantic-release/git": "^10.0.1",