prq-cli 0.2.0 → 0.4.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/README.md CHANGED
@@ -52,6 +52,15 @@ prq open superdoc-dev/superdoc#482 # opens directly
52
52
  prq open https://github.com/org/repo/pull/482
53
53
  ```
54
54
 
55
+ ### `prq review <identifier>`
56
+
57
+ Open a PR's "Files changed" tab for review.
58
+
59
+ ```bash
60
+ prq review 482
61
+ prq review superdoc-dev/superdoc#482
62
+ ```
63
+
55
64
  ### `prq nudge <identifier>`
56
65
 
57
66
  Post a comment on a PR asking if it's still active.
package/dist/bin/prq.js CHANGED
@@ -6411,30 +6411,71 @@ async function nudgeCommand(identifier, config, options) {
6411
6411
  console.log(source_default.green(` Comment posted on ${label}`));
6412
6412
  }
6413
6413
 
6414
- // src/platform.ts
6414
+ // src/actions.ts
6415
6415
  import { spawn } from "node:child_process";
6416
- function openUrl(url) {
6417
- return new Promise((resolve, reject) => {
6418
- const cmd = process.platform === "darwin" ? "open" : process.platform === "linux" ? "xdg-open" : process.platform === "win32" ? "cmd" : null;
6419
- if (!cmd) {
6420
- reject(new Error(`Unsupported platform: ${process.platform}`));
6421
- return;
6416
+ var DEFAULT_ACTIONS = {
6417
+ open: "open {url}",
6418
+ review: "open {url}/files",
6419
+ nudge: "gh pr comment {number} --repo {owner}/{repo} --body 'Hey @{author}, is this PR still active? No activity for {days} days.'"
6420
+ };
6421
+ function getAction(name, config) {
6422
+ return config.actions[name] ?? DEFAULT_ACTIONS[name];
6423
+ }
6424
+ function listActions(config) {
6425
+ return { ...DEFAULT_ACTIONS, ...config.actions };
6426
+ }
6427
+ function buildContext(pr) {
6428
+ const days = Math.floor((Date.now() - new Date(pr.updatedAt || Date.now()).getTime()) / 86400000);
6429
+ return {
6430
+ url: pr.url,
6431
+ number: pr.number,
6432
+ owner: pr.owner,
6433
+ repo: pr.repo,
6434
+ fullRepo: `${pr.owner}/${pr.repo}`,
6435
+ title: pr.title,
6436
+ author: pr.author,
6437
+ days
6438
+ };
6439
+ }
6440
+ function interpolate(template, context) {
6441
+ return template.replace(/\{(\w+)\}/g, (match, key) => {
6442
+ if (key in context) {
6443
+ return String(context[key]);
6422
6444
  }
6423
- const args = process.platform === "win32" ? ["/c", "start", url] : [url];
6424
- const child = spawn(cmd, args, { stdio: "ignore", detached: true });
6425
- child.unref();
6445
+ return match;
6446
+ });
6447
+ }
6448
+ function executeCommand(command) {
6449
+ return new Promise((resolve, reject) => {
6450
+ const child = spawn(command, {
6451
+ shell: true,
6452
+ stdio: "inherit"
6453
+ });
6426
6454
  child.on("error", reject);
6427
- child.on("close", () => resolve());
6455
+ child.on("close", (code) => {
6456
+ if (code === 0)
6457
+ resolve();
6458
+ else
6459
+ reject(new Error(`Command exited with code ${code}`));
6460
+ });
6428
6461
  });
6429
6462
  }
6430
6463
 
6431
- // src/commands/open.ts
6432
- async function openCommand(identifier, config) {
6464
+ // src/commands/run.ts
6465
+ async function runCommand(action, identifier, config) {
6466
+ const template = getAction(action, config);
6467
+ if (!template) {
6468
+ const available = Object.keys(listActions(config)).join(", ");
6469
+ throw new Error(`Unknown action: "${action}"
6470
+ Available actions: ${available}`);
6471
+ }
6433
6472
  const pr = await resolveIdentifier(identifier, config);
6473
+ const context = buildContext(pr);
6474
+ const command = interpolate(template, context);
6434
6475
  const label = `${pr.owner}/${pr.repo}#${pr.number}`;
6435
- process.stderr.write(source_default.dim(`Opening ${label}...
6476
+ process.stderr.write(source_default.dim(`${label} ${action}: ${command}
6436
6477
  `));
6437
- await openUrl(pr.url);
6478
+ await executeCommand(command);
6438
6479
  }
6439
6480
 
6440
6481
  // src/categorize.ts
@@ -10622,7 +10663,8 @@ var NEVER = INVALID;
10622
10663
  var configSchema = exports_external.object({
10623
10664
  repos: exports_external.array(exports_external.string()).default([]),
10624
10665
  staleDays: exports_external.number().default(3),
10625
- user: exports_external.string().optional()
10666
+ user: exports_external.string().optional(),
10667
+ actions: exports_external.record(exports_external.string()).default({})
10626
10668
  });
10627
10669
  function loadConfig(cliOverrides) {
10628
10670
  const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
@@ -10666,7 +10708,11 @@ function createCLI() {
10666
10708
  });
10667
10709
  program2.command("open <identifier>").description("Open a PR in the browser").action(async (identifier) => {
10668
10710
  const config = loadConfig({});
10669
- await openCommand(identifier, config);
10711
+ await runCommand("open", identifier, config);
10712
+ });
10713
+ program2.command("review <identifier>").description("Open PR files changed tab for review").action(async (identifier) => {
10714
+ const config = loadConfig({});
10715
+ await runCommand("review", identifier, config);
10670
10716
  });
10671
10717
  program2.command("nudge <identifier>").description("Post a nudge comment on a PR").option("-m, --message <msg>", "Custom nudge message").option("-y, --yes", "Skip confirmation").action(async (identifier, opts) => {
10672
10718
  const config = loadConfig({});
@@ -10675,6 +10721,10 @@ function createCLI() {
10675
10721
  yes: opts.yes ?? false
10676
10722
  });
10677
10723
  });
10724
+ program2.command("run <action> <identifier>").description("Run a custom action on a PR").action(async (action, identifier) => {
10725
+ const config = loadConfig({});
10726
+ await runCommand(action, identifier, config);
10727
+ });
10678
10728
  program2.command("init").description("Create config file interactively").action(async () => {
10679
10729
  await initCommand();
10680
10730
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prq-cli",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "PR Queue — see what code reviews need your attention",
5
5
  "type": "module",
6
6
  "bin": {