greview-cli 0.12.4 → 0.13.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 (3) hide show
  1. package/README.md +9 -3
  2. package/dist/cli.js +472 -70
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -8,12 +8,18 @@ Read and reply to review comments attached to local Git diffs.
8
8
  npm install --global greview-cli
9
9
  ```
10
10
 
11
- The npm package is named `greview-cli`; it installs the `greview` command.
11
+ The npm package is named `greview-cli`; it installs the `greview` command. Run
12
+ the guided setup to install the VS Code extension, agent skill, or both:
12
13
 
13
- Install the companion agent skill:
14
+ ```sh
15
+ greview setup
16
+ ```
17
+
18
+ Install one component directly:
14
19
 
15
20
  ```sh
16
- greview install-skill
21
+ greview setup skill
22
+ greview setup extension
17
23
  ```
18
24
 
19
25
  ## Quick start
package/dist/cli.js CHANGED
@@ -4,6 +4,7 @@
4
4
  import { parseArgs } from "node:util";
5
5
  import { readFileSync as readFileSync2 } from "node:fs";
6
6
  import { spawn, spawnSync as spawnSync2 } from "node:child_process";
7
+ import { createInterface } from "node:readline/promises";
7
8
 
8
9
  // src/anchor.ts
9
10
  function splitLines(text) {
@@ -510,6 +511,393 @@ var Store = class {
510
511
  }
511
512
  };
512
513
 
514
+ // src/help.ts
515
+ var SKILL_URL = "https://github.com/YouXam/greview/tree/main/skills/greview";
516
+ function globalHelp(version) {
517
+ return `greview ${version} - review local Git diffs with humans and coding agents
518
+
519
+ Usage:
520
+ greview <command> [options]
521
+ greview help <command>
522
+
523
+ Review threads:
524
+ list List open threads
525
+ show <id> Show a thread, its comments, and current location
526
+ add Start a thread on a line range
527
+ reply <id> Reply to a thread
528
+ edit <comment-id> Edit a comment
529
+ resolve <id> Resolve a thread
530
+ unresolve <id> Reopen a thread
531
+ rm <id> Delete a thread
532
+
533
+ Repository:
534
+ sync Re-anchor all threads
535
+ stats Show thread counts
536
+ repo Show repository details
537
+
538
+ Setup and integrations:
539
+ setup [skill|extension] Install greview components
540
+ onsubmit <command> Manage review submission hooks
541
+
542
+ Help:
543
+ help [command] Show global or command-specific help
544
+ version Print the greview version
545
+
546
+ Global options:
547
+ --cwd <dir> Run as if started in this directory
548
+ --json Emit {"ok":true,"data":...} responses
549
+ -h, --help Show help for the selected command
550
+ -v, --version Print the greview version
551
+
552
+ Agent skill:
553
+ Guide: ${SKILL_URL}
554
+ Install: greview setup skill
555
+ Direct: npx --yes skills add YouXam/greview --skill greview
556
+
557
+ Run \`greview help <command>\` for command options and examples.
558
+ `;
559
+ }
560
+ var HELP = {
561
+ list: `Usage:
562
+ greview list [options]
563
+
564
+ List review threads, freshly re-anchored against the current repository state.
565
+ Open threads are shown by default, with changed or orphaned threads first.
566
+
567
+ Options:
568
+ --all Include open and resolved threads
569
+ --resolved Show only resolved threads
570
+ --file <path> Restrict results to one file
571
+ --target <target> Restrict to worktree, index, or head
572
+ --events Include event history in JSON output
573
+ --no-sync Use the last recorded locations
574
+ --cwd <dir> Run against another checkout
575
+ --json Emit machine-readable output
576
+
577
+ Examples:
578
+ greview list
579
+ greview list --file src/api.ts --json
580
+ greview list --resolved --no-sync
581
+ `,
582
+ show: `Usage:
583
+ greview show <thread-id> [options]
584
+
585
+ Show one thread with its comments, original anchor, current region, drift notes,
586
+ and event history. The thread is re-anchored before display by default.
587
+
588
+ Options:
589
+ --no-sync Use the last recorded location
590
+ --cwd <dir> Run against another checkout
591
+ --json Emit machine-readable output
592
+
593
+ Examples:
594
+ greview show 3
595
+ greview show 3 --json
596
+ `,
597
+ add: `Usage:
598
+ greview add --file <path> --line <n|n-m> -m <text> [options]
599
+
600
+ Start a review thread on lines in a local Git diff.
601
+
602
+ Required:
603
+ --file <path> Repository-relative or local file path
604
+ --line <n|n-m> One line or an inclusive line range
605
+ -m, --message <text> Comment text; use - to read stdin
606
+
607
+ Options:
608
+ --side <side> new or old (default: new)
609
+ --target <target> worktree, index, or head (default: worktree)
610
+ --author <name> Comment author
611
+ --agent Mark the author as a coding agent
612
+ --cwd <dir> Run against another checkout
613
+ --json Emit machine-readable output
614
+
615
+ Examples:
616
+ greview add --file src/api.ts --line 41-48 -m "Handle malformed input"
617
+ greview add --file src/api.ts --line 12 --target index --side old -m -
618
+ `,
619
+ reply: `Usage:
620
+ greview reply <thread-id> -m <text> [options]
621
+
622
+ Add a comment to an existing review thread. Replying does not resolve it.
623
+
624
+ Options:
625
+ -m, --message <text> Comment text; use - to read stdin
626
+ --author <name> Comment author
627
+ --agent Mark the author as a coding agent
628
+ --cwd <dir> Run against another checkout
629
+ --json Emit machine-readable output
630
+
631
+ Examples:
632
+ greview reply 3 --agent --author codex -m "Added input validation."
633
+ printf 'Detailed reply
634
+ ' | greview reply 3 -m -
635
+ `,
636
+ edit: `Usage:
637
+ greview edit <comment-id> -m <text> [options]
638
+
639
+ Replace the body of an existing comment. Comment IDs are shown by
640
+ \`greview show <thread-id> --json\`.
641
+
642
+ Options:
643
+ -m, --message <text> Replacement text; use - to read stdin
644
+ --cwd <dir> Run against another checkout
645
+ --json Emit machine-readable output
646
+
647
+ Example:
648
+ greview edit 7 -m "Corrected reply text."
649
+ `,
650
+ resolve: `Usage:
651
+ greview resolve <thread-id> [options]
652
+
653
+ Mark a review thread as resolved. Resolution is a human review decision; coding
654
+ agents should reply to threads and leave resolution to the reviewer.
655
+
656
+ Options:
657
+ --author <name> Person recording the decision
658
+ --by <name> Explicit resolution attribution
659
+ --cwd <dir> Run against another checkout
660
+ --json Emit machine-readable output
661
+
662
+ Example:
663
+ greview resolve 3
664
+ `,
665
+ unresolve: `Usage:
666
+ greview unresolve <thread-id> [options]
667
+
668
+ Reopen a resolved review thread.
669
+
670
+ Options:
671
+ --author <name> Person recording the decision
672
+ --by <name> Explicit attribution
673
+ --cwd <dir> Run against another checkout
674
+ --json Emit machine-readable output
675
+
676
+ Example:
677
+ greview unresolve 3
678
+ `,
679
+ rm: `Usage:
680
+ greview rm <thread-id> [options]
681
+
682
+ Permanently delete a thread and all of its comments. Coding agents should never
683
+ delete review threads on behalf of the reviewer.
684
+
685
+ Options:
686
+ --cwd <dir> Run against another checkout
687
+ --json Emit machine-readable output
688
+
689
+ Example:
690
+ greview rm 3
691
+ `,
692
+ sync: `Usage:
693
+ greview sync [options]
694
+
695
+ Re-anchor every thread against the current worktree, index, and HEAD, then record
696
+ any drift or location changes.
697
+
698
+ Options:
699
+ --cwd <dir> Run against another checkout
700
+ --json Emit machine-readable output
701
+
702
+ Example:
703
+ greview sync --json
704
+ `,
705
+ stats: `Usage:
706
+ greview stats [options]
707
+
708
+ Show counts for open, resolved, changed, and orphaned threads. Locations are
709
+ refreshed before counting.
710
+
711
+ Options:
712
+ --cwd <dir> Run against another checkout
713
+ --json Emit machine-readable output
714
+
715
+ Example:
716
+ greview stats --json
717
+ `,
718
+ repo: `Usage:
719
+ greview repo [options]
720
+
721
+ Show the repository root, Git directory, current branch, HEAD commit, and greview
722
+ data path.
723
+
724
+ Options:
725
+ --cwd <dir> Start discovery from another directory
726
+ --json Emit machine-readable output
727
+
728
+ Example:
729
+ greview repo --cwd ../another-checkout
730
+ `,
731
+ setup: `Usage:
732
+ greview setup
733
+ greview setup skill
734
+ greview setup extension
735
+
736
+ Install greview components. With no component, choose the agent skill, VS Code
737
+ extension, or both interactively. Setup does not require a Git repository.
738
+
739
+ Components:
740
+ skill Run the interactive skills CLI installer
741
+ extension Install youxam.greview from the VS Code Marketplace
742
+
743
+ Requirements:
744
+ skill Node.js with npm/npx
745
+ extension The VS Code \`code\` command on PATH
746
+
747
+ Examples:
748
+ greview setup
749
+ greview setup skill
750
+ greview setup extension
751
+ `,
752
+ "setup:skill": `Usage:
753
+ greview setup skill
754
+
755
+ Install the greview agent skill from GitHub. This starts the skills CLI and keeps
756
+ its interactive choice of project/global scope and target agents.
757
+
758
+ Requirements:
759
+ Node.js with npm/npx
760
+
761
+ Equivalent command:
762
+ npx --yes skills add YouXam/greview --skill greview
763
+ `,
764
+ "setup:extension": `Usage:
765
+ greview setup extension
766
+
767
+ Install the greview extension from the VS Code Marketplace by running:
768
+ code --install-extension youxam.greview
769
+
770
+ Requirement:
771
+ The VS Code \`code\` command must be available on PATH.
772
+
773
+ Marketplace:
774
+ https://marketplace.visualstudio.com/items?itemName=youxam.greview
775
+ `,
776
+ onsubmit: `Usage:
777
+ greview onsubmit <command> [arguments] [options]
778
+
779
+ Manage commands that run when a review is submitted. Hooks belong to the current
780
+ worktree, run concurrently through the shell, and receive no arguments.
781
+
782
+ Commands:
783
+ list List hooks
784
+ add <name> <command> Add or replace a hook
785
+ delete <name> Delete one hook
786
+ clear Delete all hooks
787
+ run Run all hooks now
788
+
789
+ Options:
790
+ --cwd <dir> Run against another checkout
791
+ --json Emit machine-readable output
792
+
793
+ Examples:
794
+ greview onsubmit list
795
+ greview help onsubmit add
796
+ `,
797
+ "onsubmit:list": `Usage:
798
+ greview onsubmit list [options]
799
+
800
+ List review submission hooks configured for the current worktree.
801
+
802
+ Options:
803
+ --cwd <dir> Run against another checkout
804
+ --json Emit machine-readable output
805
+
806
+ Example:
807
+ greview onsubmit list --json
808
+ `,
809
+ "onsubmit:add": `Usage:
810
+ greview onsubmit add <name> <command> [options]
811
+
812
+ Add a review submission hook, or replace the hook with the same name. The command
813
+ runs through the shell at the repository root and receives no arguments.
814
+
815
+ Options:
816
+ --cwd <dir> Run against another checkout
817
+ --json Emit machine-readable output
818
+
819
+ Example:
820
+ greview onsubmit add notify "./scripts/notify-review.sh"
821
+ `,
822
+ "onsubmit:delete": `Usage:
823
+ greview onsubmit delete <name> [options]
824
+
825
+ Delete one review submission hook from the current worktree.
826
+
827
+ Options:
828
+ --cwd <dir> Run against another checkout
829
+ --json Emit machine-readable output
830
+
831
+ Example:
832
+ greview onsubmit delete notify
833
+ `,
834
+ "onsubmit:clear": `Usage:
835
+ greview onsubmit clear [options]
836
+
837
+ Delete every review submission hook from the current worktree.
838
+
839
+ Options:
840
+ --cwd <dir> Run against another checkout
841
+ --json Emit machine-readable output
842
+
843
+ Example:
844
+ greview onsubmit clear
845
+ `,
846
+ "onsubmit:run": `Usage:
847
+ greview onsubmit run [options]
848
+
849
+ Run all review submission hooks concurrently. Each hook has a one-minute timeout;
850
+ the command exits non-zero if any hook fails.
851
+
852
+ Options:
853
+ --cwd <dir> Run against another checkout
854
+ --json Emit machine-readable hook results
855
+
856
+ Example:
857
+ greview onsubmit run --json
858
+ `,
859
+ help: `Usage:
860
+ greview help [command]
861
+ greview <command> --help
862
+
863
+ Show global help or detailed help for a command. Nested onsubmit commands also
864
+ have their own pages.
865
+
866
+ Examples:
867
+ greview help add
868
+ greview list --help
869
+ greview help onsubmit add
870
+ `,
871
+ version: `Usage:
872
+ greview version
873
+ greview --version
874
+
875
+ Print the installed greview CLI version.
876
+ `
877
+ };
878
+ var ALIASES = {
879
+ ls: "list",
880
+ delete: "rm",
881
+ reopen: "unresolve"
882
+ };
883
+ var ONSUBMIT_ALIASES = {
884
+ rm: "delete"
885
+ };
886
+ function commandHelp(parts) {
887
+ const rawCommand = parts[0];
888
+ if (rawCommand === void 0) return null;
889
+ const command = ALIASES[rawCommand] ?? rawCommand;
890
+ if (command === "setup") {
891
+ const component = parts[1];
892
+ return component === void 0 ? HELP.setup ?? null : HELP[`setup:${component}`] ?? null;
893
+ }
894
+ if (command !== "onsubmit") return HELP[command] ?? null;
895
+ const rawSubcommand = parts[1];
896
+ if (rawSubcommand === void 0) return HELP.onsubmit ?? null;
897
+ const subcommand = ONSUBMIT_ALIASES[rawSubcommand] ?? rawSubcommand;
898
+ return HELP[`onsubmit:${subcommand}`] ?? null;
899
+ }
900
+
513
901
  // src/sync.ts
514
902
  var VERSIONS = ["worktree", "index", "head"];
515
903
  function intact(d) {
@@ -820,66 +1208,6 @@ function packageVersion() {
820
1208
  return pkg.version;
821
1209
  }
822
1210
  var VERSION = packageVersion();
823
- var USAGE = `greview ${VERSION} \u2014 review threads anchored to git diffs
824
-
825
- Usage: greview <command> [options]
826
-
827
- Commands
828
- list List threads (open ones by default)
829
- show <id> One thread in full, with before/after and history
830
- add Start a thread on a line range
831
- reply <id> -m <text> Add a comment to a thread
832
- edit <comment-id> -m <t> Rewrite one comment (ids shown by "show")
833
- resolve <id> Mark resolved unresolve <id> reopen
834
- rm <id> Delete a thread and its comments
835
- sync Re-anchor every thread and record what moved
836
- stats Counts, for status lines and hooks
837
- repo Repo root, git dir and database path
838
- install-skill Install the greview skill for coding agents
839
- onsubmit <sub> Commands to run when the reviewer presses Submit:
840
- list show this worktree's hooks
841
- add <name> <command> add or replace one
842
- delete <name> remove one
843
- clear remove all
844
- run run them all, concurrently
845
-
846
- Options
847
- --cwd <dir> Run as if in this directory (default: cwd)
848
- --json Machine-readable output; every response is
849
- {"ok":true,"data":...} or {"ok":false,"error":"..."}
850
-
851
- list/show
852
- --all Include resolved threads
853
- --resolved Only resolved threads
854
- --file <path> Restrict to one file
855
- --target <t> Restrict to worktree | index | head
856
- --events Include the event history in --json output
857
- --no-sync Skip re-anchoring; report the last known positions
858
-
859
- add
860
- --file <path> File to comment on (required)
861
- --line <n|n-m> Line range in the current version (required)
862
- --side new|old Diff side (default: new)
863
- --target worktree|index|head
864
- Which diff the comment belongs to (default: worktree)
865
- -m, --message <text> Comment body; use "-" to read stdin
866
-
867
- add/reply/edit/resolve
868
- --author <name> Default: $GREVIEW_AUTHOR, then git config user.name for
869
- a person, or the agent's own name for an agent
870
- --agent Record the author as an agent rather than a human.
871
- Implied when $AI_AGENT or $CLAUDECODE is set; override
872
- with GREVIEW_AUTHOR_KIND=human. An agent is never
873
- recorded under git config user.name.
874
-
875
- Submit hooks are per-worktree and run through the shell with no arguments. They
876
- are how something outside greview hears that a review is ready; greview does not
877
- care what they do.
878
-
879
- Anchoring: a thread stores the exact text of the lines it was written against.
880
- Later, "drift" says what became of them \u2014 current, moved, changed or orphaned.
881
- Nothing is ever auto-resolved; resolving is a human decision.
882
- `;
883
1211
  var UsageError = class extends Error {
884
1212
  };
885
1213
  var SKILL_INSTALL_ARGS = [
@@ -890,24 +1218,85 @@ var SKILL_INSTALL_ARGS = [
890
1218
  "--skill",
891
1219
  "greview"
892
1220
  ];
1221
+ var EXTENSION_ID = "youxam.greview";
1222
+ var MARKETPLACE_URL = `https://marketplace.visualstudio.com/items?itemName=${EXTENSION_ID}`;
893
1223
  function fail(message) {
894
1224
  throw new UsageError(message);
895
1225
  }
896
- function cmdInstallSkill() {
897
- const executable = process.platform === "win32" ? "npx.cmd" : "npx";
898
- const result = spawnSync2(executable, SKILL_INSTALL_ARGS, { stdio: "inherit" });
1226
+ function runInstaller(executable, args, missingHelp) {
1227
+ const result = spawnSync2(executable, args, { stdio: "inherit" });
899
1228
  if (result.error) {
900
- process.stderr.write(`greview: could not start npx: ${result.error.message}
1229
+ process.stderr.write(`greview: could not start ${executable}: ${result.error.message}
1230
+ ${missingHelp}
901
1231
  `);
902
1232
  return 1;
903
1233
  }
904
1234
  if (result.signal) {
905
- process.stderr.write(`greview: skill installer stopped by ${result.signal}
1235
+ process.stderr.write(`greview: ${executable} stopped by ${result.signal}
906
1236
  `);
907
1237
  return 1;
908
1238
  }
909
1239
  return result.status ?? 1;
910
1240
  }
1241
+ function installSkill() {
1242
+ const executable = process.platform === "win32" ? "npx.cmd" : "npx";
1243
+ return runInstaller(
1244
+ executable,
1245
+ SKILL_INSTALL_ARGS,
1246
+ "Install Node.js with npm, then run `greview setup skill` again."
1247
+ );
1248
+ }
1249
+ function installExtension() {
1250
+ const executable = process.platform === "win32" ? "code.cmd" : "code";
1251
+ return runInstaller(
1252
+ executable,
1253
+ ["--install-extension", EXTENSION_ID],
1254
+ `Install from ${MARKETPLACE_URL}, or add the VS Code \`code\` command to PATH.`
1255
+ );
1256
+ }
1257
+ function installComponents(components) {
1258
+ let status = 0;
1259
+ for (const component of components) {
1260
+ const result = component === "skill" ? installSkill() : installExtension();
1261
+ if (result !== 0) status = result;
1262
+ }
1263
+ return status;
1264
+ }
1265
+ async function interactiveSetup() {
1266
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
1267
+ let components = null;
1268
+ try {
1269
+ process.stdout.write(
1270
+ "greview setup\n\n 1) Agent skill\n 2) VS Code extension\n 3) Both\n\n"
1271
+ );
1272
+ const answer = (await rl.question("Select components [1-3, q to cancel]: ")).trim().toLowerCase();
1273
+ if (answer === "1" || answer === "skill") components = ["skill"];
1274
+ else if (answer === "2" || answer === "extension") components = ["extension"];
1275
+ else if (answer === "3" || answer === "both") components = ["skill", "extension"];
1276
+ else if (answer === "q" || answer === "quit" || answer === "") return 0;
1277
+ else {
1278
+ process.stderr.write(`greview: unknown setup selection "${answer}"
1279
+ `);
1280
+ return 2;
1281
+ }
1282
+ } finally {
1283
+ rl.close();
1284
+ }
1285
+ if (components === null) return 0;
1286
+ return installComponents(components);
1287
+ }
1288
+ function cmdSetup(positionals) {
1289
+ if (positionals.length > 2) {
1290
+ process.stderr.write("greview: usage: greview setup [skill|extension]\n");
1291
+ return 2;
1292
+ }
1293
+ const component = positionals[1];
1294
+ if (component === void 0) return interactiveSetup();
1295
+ if (component === "skill" || component === "extension") return installComponents([component]);
1296
+ process.stderr.write(`greview: unknown setup component "${component}" (skill or extension)
1297
+ `);
1298
+ return 2;
1299
+ }
911
1300
  function parse(argv) {
912
1301
  return parseArgs({
913
1302
  args: argv,
@@ -1315,6 +1704,21 @@ function cmdStats(ctx) {
1315
1704
  )
1316
1705
  );
1317
1706
  }
1707
+ function printHelp(parts) {
1708
+ if (parts.length === 0) {
1709
+ process.stdout.write(globalHelp(VERSION));
1710
+ return 0;
1711
+ }
1712
+ const text = commandHelp(parts);
1713
+ if (text === null) {
1714
+ process.stderr.write(`greview: no help topic for "${parts.join(" ")}"
1715
+ Try: greview help
1716
+ `);
1717
+ return 2;
1718
+ }
1719
+ process.stdout.write(text);
1720
+ return 0;
1721
+ }
1318
1722
  function main(argv) {
1319
1723
  let values;
1320
1724
  let positionals;
@@ -1326,16 +1730,14 @@ function main(argv) {
1326
1730
  return 2;
1327
1731
  }
1328
1732
  const command = positionals[0] ?? (values.version ? "version" : "help");
1329
- if (values.help || command === "help") {
1330
- process.stdout.write(USAGE);
1331
- return 0;
1332
- }
1733
+ if (command === "help") return printHelp(positionals.slice(1));
1734
+ if (values.help) return printHelp(positionals);
1333
1735
  if (command === "version") {
1334
1736
  process.stdout.write(`${VERSION}
1335
1737
  `);
1336
1738
  return 0;
1337
1739
  }
1338
- if (command === "install-skill") return cmdInstallSkill();
1740
+ if (command === "setup") return cmdSetup(positionals);
1339
1741
  let ctx = null;
1340
1742
  try {
1341
1743
  const repo = findRepo(cwdOf(values));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "greview-cli",
3
- "version": "0.12.4",
3
+ "version": "0.13.0",
4
4
  "description": "Review local Git diffs with humans and coding agents",
5
5
  "license": "MIT",
6
6
  "type": "module",