@gw-tools/gw 0.20.7 → 0.20.8

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
@@ -36,36 +36,42 @@ A command-line tool for managing git worktrees, built with Deno.
36
36
  - [Arguments](#arguments-2)
37
37
  - [Examples](#examples-2)
38
38
  - [How It Works](#how-it-works-1)
39
- - [update](#update)
39
+ - [pr](#pr)
40
+ - [Arguments](#arguments-3)
40
41
  - [Options](#options-1)
41
42
  - [Examples](#examples-3)
43
+ - [Requirements](#requirements)
42
44
  - [How It Works](#how-it-works-2)
43
- - [install-shell](#install-shell)
45
+ - [update](#update)
44
46
  - [Options](#options-2)
45
47
  - [Examples](#examples-4)
46
- - [root](#root)
47
- - [Examples](#examples-5)
48
48
  - [How It Works](#how-it-works-3)
49
- - [init](#init)
49
+ - [install-shell](#install-shell)
50
50
  - [Options](#options-3)
51
+ - [Examples](#examples-5)
52
+ - [root](#root)
53
+ - [Examples](#examples-6)
54
+ - [How It Works](#how-it-works-4)
55
+ - [init](#init)
56
+ - [Options](#options-4)
51
57
  - [Clone Examples](#clone-examples)
52
58
  - [Existing Repository Examples](#existing-repository-examples)
53
59
  - [Hook Variables](#hook-variables)
54
60
  - [Auto-Cleanup Configuration](#auto-cleanup-configuration)
55
61
  - [When to Use](#when-to-use)
56
62
  - [show-init](#show-init)
57
- - [Options](#options-4)
58
- - [Examples](#examples-6)
63
+ - [Options](#options-5)
64
+ - [Examples](#examples-7)
59
65
  - [Output Example](#output-example)
60
66
  - [When to Use](#when-to-use-1)
61
67
  - [sync](#sync)
62
- - [Arguments](#arguments-3)
63
- - [Options](#options-5)
64
- - [Examples](#examples-7)
65
- - [clean](#clean)
68
+ - [Arguments](#arguments-4)
66
69
  - [Options](#options-6)
67
70
  - [Examples](#examples-8)
68
- - [How It Works](#how-it-works-4)
71
+ - [clean](#clean)
72
+ - [Options](#options-7)
73
+ - [Examples](#examples-9)
74
+ - [How It Works](#how-it-works-5)
69
75
  - [Git Worktree Proxy Commands](#git-worktree-proxy-commands)
70
76
  - [list (ls)](#list-ls)
71
77
  - [remove (rm)](#remove-rm)
@@ -137,14 +143,14 @@ npx skills add https://github.com/mthines/gw-tools --skill @gw-git-worktree-work
137
143
  ```
138
144
 
139
145
  ```bash
146
+ # Autonomous feature development workflow
147
+ npx skills add https://github.com/mthines/gw-tools --skill @gw-autonomous-workflow
148
+
140
149
  # Master Git worktrees and gw workflows
141
150
  npx skills add https://github.com/mthines/gw-tools --skill @gw-git-worktree-workflows
142
151
 
143
152
  # Configure gw for your project type (Next.js, monorepos, etc.)
144
153
  npx skills add https://github.com/mthines/gw-tools --skill @gw-config-management
145
-
146
- # Autonomous feature development workflow
147
- npx skills add https://github.com/mthines/gw-tools --skill @gw-autonomous-workflow
148
154
  ```
149
155
 
150
156
  Once installed, your AI agent can:
@@ -611,6 +617,75 @@ The `checkout` command intelligently handles four scenarios:
611
617
 
612
618
  **Use case:** When updating your feature branch with latest changes, you might instinctively try `git checkout main && git pull`. With worktrees, this fails because main is checked out elsewhere. Instead, use `gw update` to update your current branch with main, or use `gw checkout main` to navigate to the main worktree.
613
619
 
620
+ ### pr
621
+
622
+ Check out a pull request into a new worktree. This command fetches a PR's branch and creates a worktree for it in one step, making it easy to review, test, or contribute to pull requests.
623
+
624
+ ```bash
625
+ gw pr <pr-number|pr-url>
626
+ ```
627
+
628
+ When you want to review or test a pull request, you typically need to:
629
+
630
+ 1. Find the PR's branch name
631
+ 2. Fetch the branch (especially for forks)
632
+ 3. Create a worktree for it
633
+ 4. Navigate to the worktree
634
+
635
+ The `gw pr` command does all of this in a single step.
636
+
637
+ #### Arguments
638
+
639
+ - `<pr-number|pr-url>`: PR number (e.g., 42) or GitHub PR URL
640
+
641
+ #### Options
642
+
643
+ - `--name <name>`: Custom name for the worktree directory (defaults to PR's branch name)
644
+ - `--no-cd`: Don't navigate to the new worktree after creation
645
+ - `-h, --help`: Show help message
646
+
647
+ #### Examples
648
+
649
+ ```bash
650
+ # Check out PR #42
651
+ gw pr 42
652
+
653
+ # Check out PR by URL
654
+ gw pr https://github.com/user/repo/pull/42
655
+
656
+ # Use custom worktree name
657
+ gw pr 42 --name review-feature
658
+
659
+ # Check out without auto-navigation
660
+ gw pr 42 --no-cd
661
+ ```
662
+
663
+ #### Requirements
664
+
665
+ - **GitHub CLI (gh)** must be installed and authenticated
666
+ - Install from: https://cli.github.com/
667
+ - After installation, authenticate with: `gh auth login`
668
+
669
+ #### How It Works
670
+
671
+ 1. **Resolves PR info**: Uses `gh pr view` to get the PR's branch name and fork information
672
+ 2. **Validates URL** (if provided): Ensures the PR URL matches the current repository
673
+ 3. **Checks for existing worktree**: If the branch is already checked out, offers to navigate there
674
+ 4. **Fetches PR branch**: Uses `git fetch origin pull/<number>/head:<branch>` pattern which works for both same-repo and fork PRs
675
+ 5. **Creates worktree**: Creates a new worktree with the PR's branch
676
+ 6. **Copies files**: Auto-copies files from `autoCopyFiles` config (same as `gw add`)
677
+ 7. **Runs hooks**: Executes pre-add and post-add hooks (same as `gw add`)
678
+ 8. **Navigates**: Automatically navigates to the new worktree
679
+
680
+ **Fork Handling:**
681
+ The command automatically handles PRs from forks by using GitHub's `pull/<number>/head` ref pattern. This fetches the PR branch without needing to add the fork as a remote.
682
+
683
+ **Error Handling:**
684
+
685
+ - If `gh` is not installed, shows installation instructions
686
+ - If PR is not found, shows helpful error with authentication hint
687
+ - If PR URL is for a different repository, shows clear error message
688
+
614
689
  ### update
615
690
 
616
691
  Update your current worktree with the latest changes from the default branch (or specified branch) using either merge or rebase strategy. This is useful when you want to update your feature branch with the latest changes from main without having to switch worktrees.
package/install.js CHANGED
@@ -5,14 +5,7 @@
5
5
  * Downloads the appropriate binary for the current platform
6
6
  */
7
7
 
8
- const {
9
- existsSync,
10
- mkdirSync,
11
- chmodSync,
12
- openSync,
13
- fsyncSync,
14
- closeSync,
15
- } = require('fs');
8
+ const { existsSync, mkdirSync, chmodSync, openSync, fsyncSync, closeSync } = require('fs');
16
9
  const { join } = require('path');
17
10
  const { arch, platform } = require('os');
18
11
  const https = require('https');
@@ -46,7 +39,7 @@ function getBinaryName() {
46
39
  if (!os || !cpu) {
47
40
  console.error(
48
41
  `Unsupported platform: ${platform()}-${arch()}\n` +
49
- 'Supported platforms: macOS (x64, arm64), Linux (x64, arm64), Windows (x64, arm64)',
42
+ 'Supported platforms: macOS (x64, arm64), Linux (x64, arm64), Windows (x64, arm64)'
50
43
  );
51
44
  process.exit(1);
52
45
  }
@@ -63,39 +56,29 @@ function download(url, dest) {
63
56
  const file = createWriteStream(dest);
64
57
 
65
58
  https
66
- .get(
67
- url,
68
- { headers: { 'User-Agent': 'gw-npm-installer' } },
69
- (response) => {
70
- // Handle redirects
71
- if (response.statusCode === 302 || response.statusCode === 301) {
72
- return download(response.headers.location, dest)
73
- .then(resolve)
74
- .catch(reject);
75
- }
76
-
77
- if (response.statusCode !== 200) {
78
- reject(
79
- new Error(
80
- `Failed to download: ${response.statusCode} ${response.statusMessage}`,
81
- ),
82
- );
83
- return;
84
- }
85
-
86
- response.pipe(file);
87
-
88
- file.on('finish', () => {
89
- file.close((err) => {
90
- if (err) {
91
- reject(err);
92
- } else {
93
- resolve();
94
- }
95
- });
59
+ .get(url, { headers: { 'User-Agent': 'gw-npm-installer' } }, (response) => {
60
+ // Handle redirects
61
+ if (response.statusCode === 302 || response.statusCode === 301) {
62
+ return download(response.headers.location, dest).then(resolve).catch(reject);
63
+ }
64
+
65
+ if (response.statusCode !== 200) {
66
+ reject(new Error(`Failed to download: ${response.statusCode} ${response.statusMessage}`));
67
+ return;
68
+ }
69
+
70
+ response.pipe(file);
71
+
72
+ file.on('finish', () => {
73
+ file.close((err) => {
74
+ if (err) {
75
+ reject(err);
76
+ } else {
77
+ resolve();
78
+ }
96
79
  });
97
- },
98
- )
80
+ });
81
+ })
99
82
  .on('error', (err) => {
100
83
  reject(err);
101
84
  });
@@ -197,7 +180,7 @@ async function installShellIntegration(binaryPath, retries = 3) {
197
180
 
198
181
  try {
199
182
  child = spawn(binaryPath, ['install-shell'], {
200
- stdio: ['inherit', 'inherit', 'pipe'], // stdin, stdout, stderr
183
+ stdio: ['inherit', 'inherit', 'pipe'], // stdin, stdout, stderr
201
184
  });
202
185
  } catch (err) {
203
186
  // Catch synchronous spawn errors (e.g., ETXTBSY thrown immediately)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gw-tools/gw",
3
- "version": "0.20.7",
3
+ "version": "0.20.8",
4
4
  "description": "A command-line tool for managing git worktrees - copy files between worktrees with ease",
5
5
  "keywords": [
6
6
  "git",
package/uninstall.js CHANGED
@@ -119,7 +119,7 @@ function uninstall() {
119
119
  const result = spawnSync(binaryPath, ['install-shell', '--remove'], {
120
120
  stdio: ['inherit', 'pipe', 'pipe'],
121
121
  timeout: 5000,
122
- encoding: 'utf8'
122
+ encoding: 'utf8',
123
123
  });
124
124
 
125
125
  if (result.status === 0) {