@junheep/gwt 0.1.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 (4) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +189 -0
  3. package/bin/gwt.mjs +1459 -0
  4. package/package.json +37 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Junhee Park
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,189 @@
1
+ # gwt
2
+
3
+ `gwt` is a lightweight wrapper around native Git worktrees. It creates an
4
+ isolated worktree, prepares project-defined local files and ports, and provides
5
+ safe commands for navigating and removing worktrees.
6
+
7
+ It uses Node.js built-ins and Git. There are no runtime package dependencies.
8
+
9
+ ## Install
10
+
11
+ Requires Git and Node.js 22.12 or later.
12
+
13
+ ```sh
14
+ npm install --global @junheep/gwt
15
+ ```
16
+
17
+ To install directly from a source checkout instead:
18
+
19
+ ```sh
20
+ chmod +x bin/gwt.mjs
21
+ ln -s "$PWD/bin/gwt.mjs" ~/.local/bin/gwt
22
+ ```
23
+
24
+ Install the Zsh integration once so `gwt new`, `gwt switch`, and removal of the
25
+ current worktree can change the current shell's directory:
26
+
27
+ ```zsh
28
+ gwt shell install zsh
29
+ ```
30
+
31
+ The installer shows the line it will add to `~/.zshrc` and asks for
32
+ confirmation. The integration also provides Zsh completion for commands,
33
+ options, worktrees, and Git refs. It only changes directories; it does not load
34
+ environment variables or run project hooks.
35
+
36
+ ## Configuration
37
+
38
+ Create user configuration for the current repository:
39
+
40
+ ```sh
41
+ gwt config create
42
+ ```
43
+
44
+ This adds a project entry to `~/.config/gwt/config.json`, or
45
+ `$XDG_CONFIG_HOME/gwt/config.json` when `XDG_CONFIG_HOME` is set. Projects use
46
+ the primary remote as their identifier, such as `github.com/owner/repository`.
47
+ Repositories without a remote use their canonical path.
48
+
49
+ ```json
50
+ {
51
+ "projects": {
52
+ "github.com/owner/repository": {
53
+ "worktreeDirectory": ".worktrees",
54
+ "copyFiles": [
55
+ "apps/server/.env",
56
+ "apps/web/.env"
57
+ ],
58
+ "ports": [
59
+ "WEB_PORT",
60
+ "SERVER_PORT"
61
+ ],
62
+ "postCreate": "hooks/worktree-setup",
63
+ "preRemove": "hooks/worktree-cleanup"
64
+ }
65
+ }
66
+ }
67
+ ```
68
+
69
+ User configuration is the default and does not change the repository. If
70
+ the setup should be committed and shared, create `<repository>/.gwt.json`
71
+ instead:
72
+
73
+ ```sh
74
+ gwt config create --project
75
+ ```
76
+
77
+ If user configuration exists for the repository, its non-hook fields are copied
78
+ into the new project file. User hooks are omitted because their paths use a
79
+ different base directory. Otherwise, the command creates a default scaffold.
80
+ The project file contains the configuration fields directly:
81
+
82
+ ```json
83
+ {
84
+ "base": "origin/main",
85
+ "worktreeDirectory": ".worktrees",
86
+ "copyFiles": [
87
+ "apps/server/.env",
88
+ "apps/web/.env"
89
+ ],
90
+ "ports": [
91
+ "WEB_PORT",
92
+ "SERVER_PORT"
93
+ ],
94
+ "postCreate": "./scripts/worktree-setup",
95
+ "preRemove": "./scripts/worktree-cleanup"
96
+ }
97
+ ```
98
+
99
+ When `.gwt.json` exists, it takes precedence over the user project entry.
100
+ The two files are not merged. Run `gwt config show` to see whether user and
101
+ repository configuration is available, the location of each existing config
102
+ file, the active source, and its resolved value.
103
+
104
+ All fields are optional. Without either config, worktrees are created beneath
105
+ `.worktrees`, use the primary worktree's current commit as their base, and run
106
+ no setup actions.
107
+
108
+ - `base`: Git revision used when `--base` is omitted.
109
+ - `worktreeDirectory`: Repository-relative directory for managed worktrees.
110
+ - `copyFiles`: Ignored local files copied from the primary worktree without
111
+ overwriting an existing destination.
112
+ - `ports`: Environment variable names assigned stable ports in the range
113
+ 20000–39999.
114
+ - `postCreate`: Executable run after files and ports are prepared.
115
+ - `preRemove`: Executable run before removal.
116
+
117
+ The worktree directory is added to `.git/info/exclude`; tracked project files
118
+ are not modified.
119
+
120
+ ## Hooks
121
+
122
+ Hooks receive JSON context on stdin and these environment variables:
123
+
124
+ ```text
125
+ GWT_ID
126
+ GWT_PATH
127
+ GWT_PRIMARY_PATH
128
+ GWT_BRANCH
129
+ <each name declared in ports>
130
+ ```
131
+
132
+ Example `postCreate` hook:
133
+
134
+ ```sh
135
+ #!/bin/sh
136
+ set -eu
137
+
138
+ printf 'PORT=%s\n' "$SERVER_PORT" >> apps/server/.env
139
+ pnpm install --frozen-lockfile
140
+ ```
141
+
142
+ Hook paths in user config are resolved relative to the directory containing
143
+ `config.json`; hook paths in `.gwt.json` are resolved relative to the target
144
+ worktree. Both run with the target worktree as their working directory.
145
+
146
+ Hooks in user config are trusted because the user added them directly. Hooks
147
+ from a committed `.gwt.json` require explicit trust because they execute
148
+ repository code:
149
+
150
+ ```sh
151
+ gwt trust
152
+ ```
153
+
154
+ Approval is invalidated when `.gwt.json` or either hook changes.
155
+
156
+ ## Commands
157
+
158
+ ```sh
159
+ gwt new [branch] [--base <ref>] [--no-hooks]
160
+ gwt setup [id|branch|path] [--no-hooks]
161
+ gwt list
162
+ gwt switch [id|branch|path]
163
+ gwt info [id|branch|path]
164
+ gwt remove [id|branch|path] [--keep-branch|--discard] [--yes] [--no-hooks]
165
+ gwt trust [--revoke]
166
+ gwt config create [--project]
167
+ gwt config show
168
+ gwt shell install zsh [--dry-run] [--yes]
169
+ ```
170
+
171
+ Run `gwt --help` for the command overview, or `gwt <command> --help` for
172
+ behavior, options, and practical examples. Nested commands such as
173
+ `gwt config create --help` have their own help as well.
174
+
175
+ `gwt new` creates `scratch/<id>` when no branch is provided. The immutable ID,
176
+ assigned ports, and setup status are stored under the repository's common Git
177
+ directory at `.git/gwt/worktrees/`.
178
+
179
+ Setup failures retain the worktree and record the failure. Retry with
180
+ `gwt setup <id>` or remove it explicitly.
181
+
182
+ Run `gwt switch` without a target to open the interactive picker. Use the
183
+ arrow keys, `j`/`k`, or Ctrl-n/Ctrl-p to move; press 1–9 to select a numbered
184
+ row immediately; or press `/` to filter by branch, ID, or path. Enter switches
185
+ to the selected worktree. Escape leaves filter mode or cancels the picker.
186
+
187
+ `gwt remove` refuses dirty worktrees. It removes the branch only when
188
+ `git branch -d` considers the deletion safe. `--discard --yes` explicitly
189
+ allows dirty worktree removal and forced branch deletion.