@aku11i/phantom 2.0.0 → 2.1.1

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/package.json +1 -1
  2. package/phantom.js +184 -11
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aku11i/phantom",
3
- "version": "2.0.0",
3
+ "version": "2.1.1",
4
4
  "description": "A powerful CLI tool for managing Git worktrees for parallel development",
5
5
  "keywords": [
6
6
  "git",
package/phantom.js CHANGED
@@ -4206,7 +4206,8 @@ var phantomConfigSchema = external_exports.object({
4206
4206
  preDelete: external_exports.object({
4207
4207
  commands: external_exports.array(external_exports.string()).optional()
4208
4208
  }).passthrough().optional(),
4209
- worktreesDirectory: external_exports.string().optional()
4209
+ worktreesDirectory: external_exports.string().optional(),
4210
+ defaultBranch: external_exports.string().optional()
4210
4211
  }).passthrough();
4211
4212
  function validateConfig(config) {
4212
4213
  const result = phantomConfigSchema.safeParse(config);
@@ -5336,6 +5337,7 @@ complete -c phantom -n "__phantom_using_command" -a "list" -d "List all Git work
5336
5337
  complete -c phantom -n "__phantom_using_command" -a "where" -d "Output the filesystem path of a specific worktree"
5337
5338
  complete -c phantom -n "__phantom_using_command" -a "delete" -d "Delete a Git worktree (phantom)"
5338
5339
  complete -c phantom -n "__phantom_using_command" -a "exec" -d "Execute a command in a worktree directory"
5340
+ complete -c phantom -n "__phantom_using_command" -a "review" -d "Review changes in a worktree with a local PR review interface (experimental)"
5339
5341
  complete -c phantom -n "__phantom_using_command" -a "shell" -d "Open an interactive shell in a worktree directory"
5340
5342
  complete -c phantom -n "__phantom_using_command" -a "github" -d "GitHub integration commands"
5341
5343
  complete -c phantom -n "__phantom_using_command" -a "gh" -d "GitHub integration commands (alias)"
@@ -5381,6 +5383,11 @@ complete -c phantom -n "__phantom_using_command exec" -l tmux-vertical -d "Execu
5381
5383
  complete -c phantom -n "__phantom_using_command exec" -l tmux-horizontal -d "Execute command in horizontal split pane"
5382
5384
  complete -c phantom -n "__phantom_using_command exec" -a "(__phantom_list_worktrees)"
5383
5385
 
5386
+ # review command options
5387
+ complete -c phantom -n "__phantom_using_command review" -l fzf -d "Use fzf for interactive selection"
5388
+ complete -c phantom -n "__phantom_using_command review" -l base -d "Base reference for comparison" -x
5389
+ complete -c phantom -n "__phantom_using_command review" -a "(__phantom_list_worktrees)"
5390
+
5384
5391
  # shell command options
5385
5392
  complete -c phantom -n "__phantom_using_command shell" -l fzf -d "Use fzf for interactive selection"
5386
5393
  complete -c phantom -n "__phantom_using_command shell" -l tmux -d "Open shell in new tmux window (-t)"
@@ -5415,6 +5422,7 @@ _phantom() {
5415
5422
  'where:Output the filesystem path of a specific worktree'
5416
5423
  'delete:Delete a Git worktree (phantom)'
5417
5424
  'exec:Execute a command in a worktree directory'
5425
+ 'review:Review changes in a worktree with a local PR review interface (experimental)'
5418
5426
  'shell:Open an interactive shell in a worktree directory'
5419
5427
  'github:GitHub integration commands'
5420
5428
  'gh:GitHub integration commands (alias)'
@@ -5457,13 +5465,18 @@ _phantom() {
5457
5465
  '--fzf[Use fzf for interactive selection]' \\
5458
5466
  '--names[Output only phantom names (for scripts and completion)]'
5459
5467
  ;;
5460
- where|delete|shell)
5468
+ where|delete|review|shell)
5461
5469
  local worktrees
5462
5470
  worktrees=(\${(f)"$(phantom list --names 2>/dev/null)"})
5463
5471
  if [[ \${line[1]} == "where" ]]; then
5464
5472
  _arguments \\
5465
5473
  '--fzf[Use fzf for interactive selection]' \\
5466
5474
  '1:worktree:(\${(q)worktrees[@]})'
5475
+ elif [[ \${line[1]} == "review" ]]; then
5476
+ _arguments \\
5477
+ '--fzf[Use fzf for interactive selection]' \\
5478
+ '--base[Base reference for comparison]:reference:' \\
5479
+ '1:worktree:(\${(q)worktrees[@]})'
5467
5480
  elif [[ \${line[1]} == "shell" ]]; then
5468
5481
  _arguments \\
5469
5482
  '--fzf[Use fzf for interactive selection]' \\
@@ -5529,7 +5542,7 @@ _phantom_completion() {
5529
5542
  local cur prev words cword
5530
5543
  _init_completion || return
5531
5544
 
5532
- local commands="create attach list where delete exec shell github gh version completion mcp"
5545
+ local commands="create attach list where delete exec review shell github gh version completion mcp"
5533
5546
  local global_opts="--help --version"
5534
5547
 
5535
5548
  if [[ \${cword} -eq 1 ]]; then
@@ -5631,6 +5644,24 @@ _phantom_completion() {
5631
5644
  ;;
5632
5645
  esac
5633
5646
  ;;
5647
+ review)
5648
+ case "\${prev}" in
5649
+ --base)
5650
+ # Don't complete anything specific for base reference
5651
+ return 0
5652
+ ;;
5653
+ *)
5654
+ if [[ "\${cur}" == -* ]]; then
5655
+ local opts="--fzf --base"
5656
+ COMPREPLY=( $(compgen -W "\${opts}" -- "\${cur}") )
5657
+ else
5658
+ local worktrees=$(_phantom_list_worktrees)
5659
+ COMPREPLY=( $(compgen -W "\${worktrees}" -- "\${cur}") )
5660
+ fi
5661
+ return 0
5662
+ ;;
5663
+ esac
5664
+ ;;
5634
5665
  shell)
5635
5666
  case "\${prev}" in
5636
5667
  --tmux|-t|--tmux-vertical|--tmux-horizontal)
@@ -13267,7 +13298,7 @@ var StdioServerTransport = class {
13267
13298
  // ../mcp/package.json
13268
13299
  var package_default = {
13269
13300
  name: "@aku11i/phantom-mcp",
13270
- version: "2.0.0",
13301
+ version: "2.1.1",
13271
13302
  private: true,
13272
13303
  type: "module",
13273
13304
  main: "./src/index.ts",
@@ -13546,10 +13577,97 @@ async function mcpHandler(args2 = []) {
13546
13577
  }
13547
13578
  }
13548
13579
 
13549
- // src/handlers/shell.ts
13580
+ // src/handlers/review.ts
13550
13581
  import { parseArgs as parseArgs8 } from "node:util";
13551
- async function shellHandler(args2) {
13582
+ async function reviewHandler(args2) {
13552
13583
  const { positionals, values } = parseArgs8({
13584
+ args: args2,
13585
+ options: {
13586
+ fzf: {
13587
+ type: "boolean",
13588
+ default: false
13589
+ },
13590
+ base: {
13591
+ type: "string"
13592
+ }
13593
+ },
13594
+ strict: true,
13595
+ allowPositionals: true
13596
+ });
13597
+ const useFzf = values.fzf ?? false;
13598
+ const base = values.base;
13599
+ if (useFzf) {
13600
+ if (positionals.length > 0) {
13601
+ exitWithError(
13602
+ "Cannot specify worktree name when using --fzf",
13603
+ exitCodes.validationError
13604
+ );
13605
+ }
13606
+ } else {
13607
+ if (positionals.length !== 1) {
13608
+ exitWithError(
13609
+ "Usage: phantom review <worktree-name> [--base <ref>]",
13610
+ exitCodes.validationError
13611
+ );
13612
+ }
13613
+ }
13614
+ try {
13615
+ const gitRoot = await getGitRoot();
13616
+ const context = await createContext(gitRoot);
13617
+ let worktreeName;
13618
+ if (useFzf) {
13619
+ const selectResult = await selectWorktreeWithFzf(
13620
+ context.gitRoot,
13621
+ context.worktreesDirectory
13622
+ );
13623
+ if (isErr(selectResult)) {
13624
+ exitWithError(selectResult.error.message, exitCodes.generalError);
13625
+ }
13626
+ if (!selectResult.value) {
13627
+ exitWithSuccess();
13628
+ }
13629
+ worktreeName = selectResult.value.name;
13630
+ } else {
13631
+ worktreeName = positionals[0];
13632
+ }
13633
+ const validation = await validateWorktreeExists(
13634
+ context.gitRoot,
13635
+ context.worktreesDirectory,
13636
+ worktreeName
13637
+ );
13638
+ if (isErr(validation)) {
13639
+ exitWithError(validation.error.message, exitCodes.generalError);
13640
+ }
13641
+ const baseRef = base ?? `origin/${context.config?.defaultBranch ?? "main"}`;
13642
+ output.log(`Opening review for worktree '${worktreeName}'...`);
13643
+ output.log(
13644
+ "powered by yoshiko-pg/reviewit (https://github.com/yoshiko-pg/reviewit)"
13645
+ );
13646
+ const command2 = ["reviewit", "HEAD", baseRef];
13647
+ const result = await execInWorktree(
13648
+ context.gitRoot,
13649
+ context.worktreesDirectory,
13650
+ worktreeName,
13651
+ command2,
13652
+ { interactive: true }
13653
+ );
13654
+ if (isErr(result)) {
13655
+ const exitCode = result.error instanceof WorktreeNotFoundError ? exitCodes.notFound : result.error.exitCode || exitCodes.generalError;
13656
+ exitWithError(result.error.message, exitCode);
13657
+ }
13658
+ process.exit(result.value.exitCode);
13659
+ } catch (error) {
13660
+ exitWithError(
13661
+ error instanceof Error ? error.message : String(error),
13662
+ exitCodes.generalError
13663
+ );
13664
+ }
13665
+ }
13666
+
13667
+ // src/handlers/shell.ts
13668
+ import { parseArgs as parseArgs9 } from "node:util";
13669
+ async function shellHandler(args2) {
13670
+ const { positionals, values } = parseArgs9({
13553
13671
  args: args2,
13554
13672
  options: {
13555
13673
  fzf: {
@@ -13673,12 +13791,12 @@ async function shellHandler(args2) {
13673
13791
  }
13674
13792
 
13675
13793
  // src/handlers/version.ts
13676
- import { parseArgs as parseArgs9 } from "node:util";
13794
+ import { parseArgs as parseArgs10 } from "node:util";
13677
13795
 
13678
13796
  // package.json
13679
13797
  var package_default2 = {
13680
13798
  name: "@aku11i/phantom-cli",
13681
- version: "2.0.0",
13799
+ version: "2.1.1",
13682
13800
  private: true,
13683
13801
  type: "module",
13684
13802
  scripts: {
@@ -13706,7 +13824,7 @@ function getVersion() {
13706
13824
 
13707
13825
  // src/handlers/version.ts
13708
13826
  function versionHandler(args2 = []) {
13709
- parseArgs9({
13827
+ parseArgs10({
13710
13828
  args: args2,
13711
13829
  options: {},
13712
13830
  strict: true,
@@ -13718,9 +13836,9 @@ function versionHandler(args2 = []) {
13718
13836
  }
13719
13837
 
13720
13838
  // src/handlers/where.ts
13721
- import { parseArgs as parseArgs10 } from "node:util";
13839
+ import { parseArgs as parseArgs11 } from "node:util";
13722
13840
  async function whereHandler(args2) {
13723
- const { positionals, values } = parseArgs10({
13841
+ const { positionals, values } = parseArgs11({
13724
13842
  args: args2,
13725
13843
  options: {
13726
13844
  fzf: {
@@ -14089,6 +14207,55 @@ var listHelp = {
14089
14207
  ]
14090
14208
  };
14091
14209
 
14210
+ // src/help/review.ts
14211
+ var reviewHelp = {
14212
+ name: "review",
14213
+ description: "Review changes in a worktree with a local PR review interface (experimental)",
14214
+ usage: "phantom review [options] <worktree-name>",
14215
+ options: [
14216
+ {
14217
+ name: "--fzf",
14218
+ type: "boolean",
14219
+ description: "Use fzf for interactive worktree selection"
14220
+ },
14221
+ {
14222
+ name: "--base",
14223
+ type: "string",
14224
+ description: "Base reference for comparison (default: origin/<defaultBranch>)"
14225
+ }
14226
+ ],
14227
+ examples: [
14228
+ {
14229
+ description: "Review changes against default branch",
14230
+ command: "phantom review feature-auth"
14231
+ },
14232
+ {
14233
+ description: "Review changes against specific remote branch",
14234
+ command: "phantom review feature-login --base origin/feature-auth"
14235
+ },
14236
+ {
14237
+ description: "Review changes against local branch",
14238
+ command: "phantom review feature-auth --base main"
14239
+ },
14240
+ {
14241
+ description: "Interactive worktree selection",
14242
+ command: "phantom review --fzf"
14243
+ },
14244
+ {
14245
+ description: "Interactive selection with custom base",
14246
+ command: "phantom review --fzf --base origin/staging"
14247
+ }
14248
+ ],
14249
+ notes: [
14250
+ "\u26A0\uFE0F This is an experimental feature and may change in future versions",
14251
+ "Uses reviewit to provide a GitHub-like PR review interface locally",
14252
+ "Default base is origin/<defaultBranch> where defaultBranch is from config or 'main'",
14253
+ "The --base value is passed directly to reviewit as the comparison reference",
14254
+ "Requires reviewit to be installed separately (e.g., npm install -g reviewit)",
14255
+ "powered by yoshiko-pg/reviewit (https://github.com/yoshiko-pg/reviewit)"
14256
+ ]
14257
+ };
14258
+
14092
14259
  // src/help/shell.ts
14093
14260
  var shellHelp = {
14094
14261
  name: "shell",
@@ -14236,6 +14403,12 @@ var commands = [
14236
14403
  handler: execHandler,
14237
14404
  help: execHelp
14238
14405
  },
14406
+ {
14407
+ name: "review",
14408
+ description: "Review changes in a worktree with a local PR review interface (experimental)",
14409
+ handler: reviewHandler,
14410
+ help: reviewHelp
14411
+ },
14239
14412
  {
14240
14413
  name: "shell",
14241
14414
  description: "Open an interactive shell in a worktree directory",