@gw-tools/gw 0.20.5 → 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
@@ -7,6 +7,7 @@ A command-line tool for managing git worktrees, built with Deno.
7
7
  - [gw - Git Worktree Tools](#gw---git-worktree-tools)
8
8
  - [Table of Contents](#table-of-contents)
9
9
  - [Quick Start](#quick-start)
10
+ - [🎓 AI Skills (for Claude Code, Copilot, Cursor, etc.)](#-ai-skills-for-claude-code-copilot-cursor-etc)
10
11
  - [Initial Setup: Secrets in the Default Branch](#initial-setup-secrets-in-the-default-branch)
11
12
  - [First-Time Setup Flow](#first-time-setup-flow)
12
13
  - [Why This Matters](#why-this-matters)
@@ -35,36 +36,42 @@ A command-line tool for managing git worktrees, built with Deno.
35
36
  - [Arguments](#arguments-2)
36
37
  - [Examples](#examples-2)
37
38
  - [How It Works](#how-it-works-1)
38
- - [update](#update)
39
+ - [pr](#pr)
40
+ - [Arguments](#arguments-3)
39
41
  - [Options](#options-1)
40
42
  - [Examples](#examples-3)
43
+ - [Requirements](#requirements)
41
44
  - [How It Works](#how-it-works-2)
42
- - [install-shell](#install-shell)
45
+ - [update](#update)
43
46
  - [Options](#options-2)
44
47
  - [Examples](#examples-4)
45
- - [root](#root)
46
- - [Examples](#examples-5)
47
48
  - [How It Works](#how-it-works-3)
48
- - [init](#init)
49
+ - [install-shell](#install-shell)
49
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)
50
57
  - [Clone Examples](#clone-examples)
51
58
  - [Existing Repository Examples](#existing-repository-examples)
52
59
  - [Hook Variables](#hook-variables)
53
60
  - [Auto-Cleanup Configuration](#auto-cleanup-configuration)
54
61
  - [When to Use](#when-to-use)
55
62
  - [show-init](#show-init)
56
- - [Options](#options-4)
57
- - [Examples](#examples-6)
63
+ - [Options](#options-5)
64
+ - [Examples](#examples-7)
58
65
  - [Output Example](#output-example)
59
66
  - [When to Use](#when-to-use-1)
60
67
  - [sync](#sync)
61
- - [Arguments](#arguments-3)
62
- - [Options](#options-5)
63
- - [Examples](#examples-7)
64
- - [clean](#clean)
68
+ - [Arguments](#arguments-4)
65
69
  - [Options](#options-6)
66
70
  - [Examples](#examples-8)
67
- - [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)
68
75
  - [Git Worktree Proxy Commands](#git-worktree-proxy-commands)
69
76
  - [list (ls)](#list-ls)
70
77
  - [remove (rm)](#remove-rm)
@@ -127,6 +134,35 @@ gw cd feat/another-feature
127
134
  gw checkout main
128
135
  ```
129
136
 
137
+ ## 🎓 AI Skills (for Claude Code, Copilot, Cursor, etc.)
138
+
139
+ Enhance your AI agent with gw-tools knowledge using [skills.sh](https://skills.sh):
140
+
141
+ ```bash
142
+ npx skills add https://github.com/mthines/gw-tools --skill @gw-git-worktree-workflows @gw-config-management @gw-autonomous-workflow # installs all skills
143
+ ```
144
+
145
+ ```bash
146
+ # Autonomous feature development workflow
147
+ npx skills add https://github.com/mthines/gw-tools --skill @gw-autonomous-workflow
148
+
149
+ # Master Git worktrees and gw workflows
150
+ npx skills add https://github.com/mthines/gw-tools --skill @gw-git-worktree-workflows
151
+
152
+ # Configure gw for your project type (Next.js, monorepos, etc.)
153
+ npx skills add https://github.com/mthines/gw-tools --skill @gw-config-management
154
+ ```
155
+
156
+ Once installed, your AI agent can:
157
+
158
+ - Execute complete feature development cycles autonomously
159
+ - Create worktrees for bug fixes and features automatically
160
+ - Configure gw for your specific project type
161
+ - Navigate between worktrees and manage files
162
+ - Create tested PRs from isolated worktrees
163
+
164
+ 📖 **Skill documentation:** [skills/README.md](../../skills/README.md)
165
+
130
166
  ## Initial Setup: Secrets in the Default Branch
131
167
 
132
168
  **Important:** Before using `gw add` with auto-copy, ensure your secrets and environment files exist in your `defaultBranch` worktree (typically `main`). This worktree is the **source** from which files are copied to new worktrees.
@@ -581,6 +617,75 @@ The `checkout` command intelligently handles four scenarios:
581
617
 
582
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.
583
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
+
584
689
  ### update
585
690
 
586
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.5",
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) {