git-watchtower 1.6.0 → 1.7.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.
- package/bin/git-watchtower.js +89 -9
- package/package.json +6 -1
- package/sounds/README.md +34 -0
- package/src/casino/index.js +721 -0
- package/src/casino/sounds.js +245 -0
- package/src/cli/args.js +239 -0
- package/src/config/loader.js +329 -0
- package/src/config/schema.js +305 -0
- package/src/git/branch.js +428 -0
- package/src/git/commands.js +416 -0
- package/src/git/pr.js +111 -0
- package/src/git/remote.js +127 -0
- package/src/index.js +179 -0
- package/src/polling/engine.js +157 -0
- package/src/server/process.js +329 -0
- package/src/server/static.js +95 -0
- package/src/state/store.js +527 -0
- package/src/telemetry/analytics.js +142 -0
- package/src/telemetry/config.js +123 -0
- package/src/telemetry/index.js +93 -0
- package/src/ui/actions.js +425 -0
- package/src/ui/ansi.js +498 -0
- package/src/ui/keybindings.js +198 -0
- package/src/ui/renderer.js +1326 -0
- package/src/utils/async.js +219 -0
- package/src/utils/browser.js +40 -0
- package/src/utils/errors.js +490 -0
- package/src/utils/gitignore.js +174 -0
- package/src/utils/sound.js +33 -0
- package/src/utils/time.js +27 -0
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Casino Mode Sound Effects
|
|
3
|
+
*
|
|
4
|
+
* Plays casino-themed sounds for wins, jackpots, and losses.
|
|
5
|
+
* Uses system audio tools when available, falls back gracefully.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const { exec } = require('child_process');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const fs = require('fs');
|
|
11
|
+
|
|
12
|
+
// ============================================================================
|
|
13
|
+
// Sound Configuration
|
|
14
|
+
// ============================================================================
|
|
15
|
+
|
|
16
|
+
// Path to bundled sound files (if we add them)
|
|
17
|
+
const SOUNDS_DIR = path.join(__dirname, '../../sounds');
|
|
18
|
+
|
|
19
|
+
// System sound fallbacks by platform
|
|
20
|
+
const SYSTEM_SOUNDS = {
|
|
21
|
+
darwin: {
|
|
22
|
+
win: '/System/Library/Sounds/Glass.aiff',
|
|
23
|
+
jackpot: '/System/Library/Sounds/Hero.aiff',
|
|
24
|
+
spin: '/System/Library/Sounds/Pop.aiff',
|
|
25
|
+
loss: '/System/Library/Sounds/Basso.aiff',
|
|
26
|
+
},
|
|
27
|
+
linux: {
|
|
28
|
+
win: '/usr/share/sounds/freedesktop/stereo/complete.oga',
|
|
29
|
+
jackpot: '/usr/share/sounds/freedesktop/stereo/bell.oga',
|
|
30
|
+
spin: '/usr/share/sounds/freedesktop/stereo/message.oga',
|
|
31
|
+
loss: '/usr/share/sounds/freedesktop/stereo/dialog-error.oga',
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// Volume levels (0.0 - 1.0, not all platforms support this)
|
|
36
|
+
const VOLUME = {
|
|
37
|
+
win: 0.5,
|
|
38
|
+
jackpot: 0.8,
|
|
39
|
+
spin: 0.3,
|
|
40
|
+
loss: 0.6,
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
// ============================================================================
|
|
44
|
+
// Sound Playback
|
|
45
|
+
// ============================================================================
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Play a sound file (non-blocking)
|
|
49
|
+
* @param {string} soundPath - Path to sound file
|
|
50
|
+
* @param {number} [volume=0.5] - Volume level (0.0-1.0)
|
|
51
|
+
*/
|
|
52
|
+
function playFile(soundPath, volume = 0.5) {
|
|
53
|
+
if (!soundPath) return;
|
|
54
|
+
|
|
55
|
+
const { platform } = process;
|
|
56
|
+
|
|
57
|
+
try {
|
|
58
|
+
if (platform === 'darwin') {
|
|
59
|
+
// macOS: afplay with volume
|
|
60
|
+
exec(`afplay -v ${volume} "${soundPath}" 2>/dev/null &`);
|
|
61
|
+
} else if (platform === 'linux') {
|
|
62
|
+
// Linux: paplay (PulseAudio) or aplay (ALSA)
|
|
63
|
+
// Note: paplay doesn't support volume easily, aplay does via amixer
|
|
64
|
+
exec(
|
|
65
|
+
`paplay "${soundPath}" 2>/dev/null || aplay -q "${soundPath}" 2>/dev/null &`
|
|
66
|
+
);
|
|
67
|
+
} else if (platform === 'win32') {
|
|
68
|
+
// Windows: Use PowerShell to play sound
|
|
69
|
+
exec(
|
|
70
|
+
`powershell -c "(New-Object Media.SoundPlayer '${soundPath}').PlaySync()" 2>nul`,
|
|
71
|
+
{ windowsHide: true }
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
} catch (e) {
|
|
75
|
+
// Silently fail - sounds are optional
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Play terminal bell as fallback
|
|
81
|
+
*/
|
|
82
|
+
function playBell() {
|
|
83
|
+
process.stdout.write('\x07');
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Get the appropriate sound file for a sound type
|
|
88
|
+
* @param {string} soundType - 'win', 'jackpot', 'spin', or 'loss'
|
|
89
|
+
* @returns {string|null}
|
|
90
|
+
*/
|
|
91
|
+
function getSoundPath(soundType) {
|
|
92
|
+
const { platform } = process;
|
|
93
|
+
|
|
94
|
+
// First check for bundled sounds
|
|
95
|
+
const bundledPath = path.join(SOUNDS_DIR, `${soundType}.wav`);
|
|
96
|
+
if (fs.existsSync(bundledPath)) {
|
|
97
|
+
return bundledPath;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Fall back to system sounds
|
|
101
|
+
const systemSounds = SYSTEM_SOUNDS[platform];
|
|
102
|
+
if (systemSounds && systemSounds[soundType]) {
|
|
103
|
+
const systemPath = systemSounds[soundType];
|
|
104
|
+
if (fs.existsSync(systemPath)) {
|
|
105
|
+
return systemPath;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// ============================================================================
|
|
113
|
+
// Casino Sound Effects
|
|
114
|
+
// ============================================================================
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Play a win sound (small to medium wins)
|
|
118
|
+
*/
|
|
119
|
+
function playWin() {
|
|
120
|
+
const soundPath = getSoundPath('win');
|
|
121
|
+
if (soundPath) {
|
|
122
|
+
playFile(soundPath, VOLUME.win);
|
|
123
|
+
} else {
|
|
124
|
+
playBell();
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Play a jackpot sound (big wins)
|
|
130
|
+
*/
|
|
131
|
+
function playJackpot() {
|
|
132
|
+
const soundPath = getSoundPath('jackpot');
|
|
133
|
+
if (soundPath) {
|
|
134
|
+
playFile(soundPath, VOLUME.jackpot);
|
|
135
|
+
} else {
|
|
136
|
+
// Multiple bells for jackpot!
|
|
137
|
+
playBell();
|
|
138
|
+
setTimeout(playBell, 200);
|
|
139
|
+
setTimeout(playBell, 400);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Play a mega jackpot sound (huge wins)
|
|
145
|
+
*/
|
|
146
|
+
function playMegaJackpot() {
|
|
147
|
+
const soundPath = getSoundPath('jackpot');
|
|
148
|
+
if (soundPath) {
|
|
149
|
+
// Play jackpot sound multiple times
|
|
150
|
+
playFile(soundPath, VOLUME.jackpot);
|
|
151
|
+
setTimeout(() => playFile(soundPath, VOLUME.jackpot), 300);
|
|
152
|
+
setTimeout(() => playFile(soundPath, VOLUME.jackpot), 600);
|
|
153
|
+
} else {
|
|
154
|
+
// Lots of bells!
|
|
155
|
+
for (let i = 0; i < 5; i++) {
|
|
156
|
+
setTimeout(playBell, i * 150);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Play slot spin sound
|
|
163
|
+
*/
|
|
164
|
+
function playSpin() {
|
|
165
|
+
const soundPath = getSoundPath('spin');
|
|
166
|
+
if (soundPath) {
|
|
167
|
+
playFile(soundPath, VOLUME.spin);
|
|
168
|
+
}
|
|
169
|
+
// No fallback for spin - it would be annoying
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Play loss/failure sound (sad trombone effect)
|
|
174
|
+
*/
|
|
175
|
+
function playLoss() {
|
|
176
|
+
const soundPath = getSoundPath('loss');
|
|
177
|
+
if (soundPath) {
|
|
178
|
+
playFile(soundPath, VOLUME.loss);
|
|
179
|
+
} else {
|
|
180
|
+
// Low-pitched bell equivalent
|
|
181
|
+
playBell();
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Play sound based on win level
|
|
187
|
+
* @param {string} levelKey - 'small', 'medium', 'large', 'huge', 'jackpot', 'mega'
|
|
188
|
+
*/
|
|
189
|
+
function playForWinLevel(levelKey) {
|
|
190
|
+
switch (levelKey) {
|
|
191
|
+
case 'small':
|
|
192
|
+
case 'medium':
|
|
193
|
+
playWin();
|
|
194
|
+
break;
|
|
195
|
+
case 'large':
|
|
196
|
+
case 'huge':
|
|
197
|
+
playJackpot();
|
|
198
|
+
break;
|
|
199
|
+
case 'jackpot':
|
|
200
|
+
playJackpot();
|
|
201
|
+
break;
|
|
202
|
+
case 'mega':
|
|
203
|
+
playMegaJackpot();
|
|
204
|
+
break;
|
|
205
|
+
default:
|
|
206
|
+
playWin();
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// ============================================================================
|
|
211
|
+
// Sound Sources Documentation
|
|
212
|
+
// ============================================================================
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* For users who want to add custom sounds:
|
|
216
|
+
*
|
|
217
|
+
* Create a 'sounds' directory in the git-watchtower root with:
|
|
218
|
+
* - win.wav - Short victory sound
|
|
219
|
+
* - jackpot.wav - Exciting jackpot fanfare
|
|
220
|
+
* - spin.wav - Slot machine spinning
|
|
221
|
+
* - loss.wav - Sad trombone / failure sound
|
|
222
|
+
*
|
|
223
|
+
* Free sound sources:
|
|
224
|
+
* - https://freesound.org/
|
|
225
|
+
* - https://mixkit.co/free-sound-effects/
|
|
226
|
+
* - https://www.zapsplat.com/
|
|
227
|
+
*
|
|
228
|
+
* Recommended search terms:
|
|
229
|
+
* - "slot machine win"
|
|
230
|
+
* - "casino jackpot"
|
|
231
|
+
* - "coin drop"
|
|
232
|
+
* - "sad trombone"
|
|
233
|
+
* - "game over"
|
|
234
|
+
*/
|
|
235
|
+
|
|
236
|
+
module.exports = {
|
|
237
|
+
playWin,
|
|
238
|
+
playJackpot,
|
|
239
|
+
playMegaJackpot,
|
|
240
|
+
playSpin,
|
|
241
|
+
playLoss,
|
|
242
|
+
playForWinLevel,
|
|
243
|
+
getSoundPath,
|
|
244
|
+
SOUNDS_DIR,
|
|
245
|
+
};
|
package/src/cli/args.js
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI argument parsing
|
|
3
|
+
* @module cli/args
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const PACKAGE_VERSION = '1.2.0';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @typedef {object} CliArgs
|
|
10
|
+
* @property {string|null} mode - Server mode override
|
|
11
|
+
* @property {boolean} noServer - Shorthand for --mode none
|
|
12
|
+
* @property {number|null} port - Port override
|
|
13
|
+
* @property {string|null} staticDir - Static directory override
|
|
14
|
+
* @property {string|null} command - Server command override
|
|
15
|
+
* @property {boolean|null} restartOnSwitch - Restart on branch switch
|
|
16
|
+
* @property {string|null} remote - Git remote name override
|
|
17
|
+
* @property {boolean|null} autoPull - Auto-pull override
|
|
18
|
+
* @property {number|null} pollInterval - Poll interval override in ms
|
|
19
|
+
* @property {boolean|null} sound - Sound override
|
|
20
|
+
* @property {number|null} visibleBranches - Visible branches override
|
|
21
|
+
* @property {boolean} init - Run configuration wizard
|
|
22
|
+
* @property {boolean} casino - Enable casino mode
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Parse CLI arguments into a structured object.
|
|
27
|
+
* @param {string[]} argv - Arguments array (typically process.argv.slice(2))
|
|
28
|
+
* @param {object} [options]
|
|
29
|
+
* @param {function} [options.onVersion] - Called when --version is encountered
|
|
30
|
+
* @param {function} [options.onHelp] - Called when --help is encountered
|
|
31
|
+
* @returns {CliArgs}
|
|
32
|
+
*/
|
|
33
|
+
function parseArgs(argv, options = {}) {
|
|
34
|
+
const args = argv || [];
|
|
35
|
+
const result = {
|
|
36
|
+
// Server settings
|
|
37
|
+
mode: null,
|
|
38
|
+
noServer: false,
|
|
39
|
+
port: null,
|
|
40
|
+
staticDir: null,
|
|
41
|
+
command: null,
|
|
42
|
+
restartOnSwitch: null,
|
|
43
|
+
// Git settings
|
|
44
|
+
remote: null,
|
|
45
|
+
autoPull: null,
|
|
46
|
+
pollInterval: null,
|
|
47
|
+
// UI settings
|
|
48
|
+
sound: null,
|
|
49
|
+
visibleBranches: null,
|
|
50
|
+
// Actions
|
|
51
|
+
init: false,
|
|
52
|
+
casino: false,
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
for (let i = 0; i < args.length; i++) {
|
|
56
|
+
// Server settings
|
|
57
|
+
if (args[i] === '--mode' || args[i] === '-m') {
|
|
58
|
+
const mode = args[i + 1];
|
|
59
|
+
if (['static', 'command', 'none'].includes(mode)) {
|
|
60
|
+
result.mode = mode;
|
|
61
|
+
}
|
|
62
|
+
i++;
|
|
63
|
+
} else if (args[i] === '--port' || args[i] === '-p') {
|
|
64
|
+
const portValue = parseInt(args[i + 1], 10);
|
|
65
|
+
if (!isNaN(portValue) && portValue > 0 && portValue < 65536) {
|
|
66
|
+
result.port = portValue;
|
|
67
|
+
}
|
|
68
|
+
i++;
|
|
69
|
+
} else if (args[i] === '--no-server' || args[i] === '-n') {
|
|
70
|
+
result.noServer = true;
|
|
71
|
+
} else if (args[i] === '--static-dir') {
|
|
72
|
+
result.staticDir = args[i + 1];
|
|
73
|
+
i++;
|
|
74
|
+
} else if (args[i] === '--command' || args[i] === '-c') {
|
|
75
|
+
result.command = args[i + 1];
|
|
76
|
+
i++;
|
|
77
|
+
} else if (args[i] === '--restart-on-switch') {
|
|
78
|
+
result.restartOnSwitch = true;
|
|
79
|
+
} else if (args[i] === '--no-restart-on-switch') {
|
|
80
|
+
result.restartOnSwitch = false;
|
|
81
|
+
}
|
|
82
|
+
// Git settings
|
|
83
|
+
else if (args[i] === '--remote' || args[i] === '-r') {
|
|
84
|
+
result.remote = args[i + 1];
|
|
85
|
+
i++;
|
|
86
|
+
} else if (args[i] === '--auto-pull') {
|
|
87
|
+
result.autoPull = true;
|
|
88
|
+
} else if (args[i] === '--no-auto-pull') {
|
|
89
|
+
result.autoPull = false;
|
|
90
|
+
} else if (args[i] === '--poll-interval') {
|
|
91
|
+
const interval = parseInt(args[i + 1], 10);
|
|
92
|
+
if (!isNaN(interval) && interval > 0) {
|
|
93
|
+
result.pollInterval = interval;
|
|
94
|
+
}
|
|
95
|
+
i++;
|
|
96
|
+
}
|
|
97
|
+
// UI settings
|
|
98
|
+
else if (args[i] === '--sound') {
|
|
99
|
+
result.sound = true;
|
|
100
|
+
} else if (args[i] === '--no-sound') {
|
|
101
|
+
result.sound = false;
|
|
102
|
+
} else if (args[i] === '--visible-branches') {
|
|
103
|
+
const count = parseInt(args[i + 1], 10);
|
|
104
|
+
if (!isNaN(count) && count > 0) {
|
|
105
|
+
result.visibleBranches = count;
|
|
106
|
+
}
|
|
107
|
+
i++;
|
|
108
|
+
} else if (args[i] === '--casino') {
|
|
109
|
+
result.casino = true;
|
|
110
|
+
}
|
|
111
|
+
// Actions and info
|
|
112
|
+
else if (args[i] === '--init') {
|
|
113
|
+
result.init = true;
|
|
114
|
+
} else if (args[i] === '--version' || args[i] === '-v') {
|
|
115
|
+
if (options.onVersion) {
|
|
116
|
+
options.onVersion(PACKAGE_VERSION);
|
|
117
|
+
}
|
|
118
|
+
} else if (args[i] === '--help' || args[i] === '-h') {
|
|
119
|
+
if (options.onHelp) {
|
|
120
|
+
options.onHelp(PACKAGE_VERSION);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return result;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Apply CLI args on top of a config object. CLI takes precedence.
|
|
129
|
+
* @param {object} config - Base configuration
|
|
130
|
+
* @param {CliArgs} cliArgs - Parsed CLI args
|
|
131
|
+
* @returns {object} Merged config
|
|
132
|
+
*/
|
|
133
|
+
function applyCliArgsToConfig(config, cliArgs) {
|
|
134
|
+
const merged = JSON.parse(JSON.stringify(config)); // deep clone
|
|
135
|
+
|
|
136
|
+
// Server settings
|
|
137
|
+
if (cliArgs.mode !== null) {
|
|
138
|
+
merged.server.mode = cliArgs.mode;
|
|
139
|
+
}
|
|
140
|
+
if (cliArgs.noServer) {
|
|
141
|
+
merged.server.mode = 'none';
|
|
142
|
+
}
|
|
143
|
+
if (cliArgs.port !== null) {
|
|
144
|
+
merged.server.port = cliArgs.port;
|
|
145
|
+
}
|
|
146
|
+
if (cliArgs.staticDir !== null) {
|
|
147
|
+
merged.server.staticDir = cliArgs.staticDir;
|
|
148
|
+
}
|
|
149
|
+
if (cliArgs.command !== null) {
|
|
150
|
+
merged.server.command = cliArgs.command;
|
|
151
|
+
}
|
|
152
|
+
if (cliArgs.restartOnSwitch !== null) {
|
|
153
|
+
merged.server.restartOnSwitch = cliArgs.restartOnSwitch;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Git settings
|
|
157
|
+
if (cliArgs.remote !== null) {
|
|
158
|
+
merged.remoteName = cliArgs.remote;
|
|
159
|
+
}
|
|
160
|
+
if (cliArgs.autoPull !== null) {
|
|
161
|
+
merged.autoPull = cliArgs.autoPull;
|
|
162
|
+
}
|
|
163
|
+
if (cliArgs.pollInterval !== null) {
|
|
164
|
+
merged.gitPollInterval = cliArgs.pollInterval;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// UI settings
|
|
168
|
+
if (cliArgs.sound !== null) {
|
|
169
|
+
merged.soundEnabled = cliArgs.sound;
|
|
170
|
+
}
|
|
171
|
+
if (cliArgs.visibleBranches !== null) {
|
|
172
|
+
merged.visibleBranches = cliArgs.visibleBranches;
|
|
173
|
+
}
|
|
174
|
+
if (cliArgs.casino) {
|
|
175
|
+
merged.casinoMode = true;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
return merged;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Get the help text for the CLI.
|
|
183
|
+
* @param {string} version
|
|
184
|
+
* @returns {string}
|
|
185
|
+
*/
|
|
186
|
+
function getHelpText(version) {
|
|
187
|
+
return `
|
|
188
|
+
Git Watchtower v${version} - Branch Monitor & Dev Server
|
|
189
|
+
|
|
190
|
+
Usage:
|
|
191
|
+
git-watchtower [options]
|
|
192
|
+
|
|
193
|
+
Server Options:
|
|
194
|
+
-m, --mode <mode> Server mode: static, command, or none
|
|
195
|
+
-p, --port <port> Server port (default: 3000)
|
|
196
|
+
-n, --no-server Shorthand for --mode none
|
|
197
|
+
--static-dir <dir> Directory for static file serving (default: public)
|
|
198
|
+
-c, --command <cmd> Command to run in command mode (e.g., "npm run dev")
|
|
199
|
+
--restart-on-switch Restart server on branch switch (default)
|
|
200
|
+
--no-restart-on-switch Don't restart server on branch switch
|
|
201
|
+
|
|
202
|
+
Git Options:
|
|
203
|
+
-r, --remote <name> Git remote name (default: origin)
|
|
204
|
+
--auto-pull Auto-pull on branch switch (default)
|
|
205
|
+
--no-auto-pull Don't auto-pull on branch switch
|
|
206
|
+
--poll-interval <ms> Git polling interval in ms (default: 5000)
|
|
207
|
+
|
|
208
|
+
UI Options:
|
|
209
|
+
--sound Enable sound notifications (default)
|
|
210
|
+
--no-sound Disable sound notifications
|
|
211
|
+
--visible-branches <n> Number of branches to display (default: 7)
|
|
212
|
+
--casino Enable casino mode
|
|
213
|
+
|
|
214
|
+
General:
|
|
215
|
+
--init Run the configuration wizard
|
|
216
|
+
-v, --version Show version number
|
|
217
|
+
-h, --help Show this help message
|
|
218
|
+
|
|
219
|
+
Server Modes:
|
|
220
|
+
static Serve static files with live reload (default)
|
|
221
|
+
command Run your own dev server (Next.js, Vite, Nuxt, etc.)
|
|
222
|
+
none Branch monitoring only
|
|
223
|
+
|
|
224
|
+
Configuration:
|
|
225
|
+
On first run, Git Watchtower will prompt you to configure settings.
|
|
226
|
+
Settings are saved to .watchtowerrc.json in your project directory.
|
|
227
|
+
CLI options override config file settings for the current session.
|
|
228
|
+
|
|
229
|
+
Examples:
|
|
230
|
+
git-watchtower # Start with config or defaults
|
|
231
|
+
git-watchtower --init # Re-run configuration wizard
|
|
232
|
+
git-watchtower --no-server # Branch monitoring only
|
|
233
|
+
git-watchtower -p 8080 # Override port
|
|
234
|
+
git-watchtower -m command -c "npm run dev" # Use custom dev server
|
|
235
|
+
git-watchtower --no-sound --poll-interval 10000
|
|
236
|
+
`;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
module.exports = { parseArgs, applyCliArgsToConfig, getHelpText, PACKAGE_VERSION };
|