@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.
- package/bin/dosu.js +108 -36
- 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.
|
|
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("
|
|
15318
|
-
cmd.command("list").description("List pending
|
|
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({
|
|
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
|
|
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
|
-
|
|
15348
|
-
|
|
15349
|
-
|
|
15350
|
-
|
|
15351
|
-
|
|
15352
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
15388
|
-
|
|
15389
|
-
|
|
15390
|
-
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
|
-
|
|
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
|
|
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
|
|
15436
|
-
|
|
15437
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
15459
|
-
page_version_id: id,
|
|
15460
|
-
|
|
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.
|
|
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.
|
|
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",
|