@solaqua/gji 0.3.0 → 0.4.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/dist/cli.js +1 -0
- package/dist/config.js +1 -0
- package/dist/index.js +25 -1
- package/dist/init.d.ts +11 -1
- package/dist/init.js +101 -18
- package/man/man1/gji-clean.1 +19 -0
- package/man/man1/gji-config.1 +19 -0
- package/man/man1/gji-go.1 +13 -0
- package/man/man1/gji-init.1 +13 -0
- package/man/man1/gji-ls.1 +13 -0
- package/man/man1/gji-new.1 +22 -0
- package/man/man1/gji-pr.1 +16 -0
- package/man/man1/gji-remove.1 +19 -0
- package/man/man1/gji-root.1 +13 -0
- package/man/man1/gji-status.1 +13 -0
- package/man/man1/gji-sync.1 +16 -0
- package/man/man1/gji-trigger-hook.1 +9 -0
- package/man/man1/gji.1 +67 -0
- package/package.json +7 -2
package/dist/cli.js
CHANGED
package/dist/config.js
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,8 +1,19 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { loadGlobalConfig } from './config.js';
|
|
2
4
|
import { runCli } from './cli.js';
|
|
3
5
|
async function main() {
|
|
4
6
|
try {
|
|
5
|
-
const
|
|
7
|
+
const argv = process.argv.slice(2);
|
|
8
|
+
// Warn once (until fixed) when shell integration hasn't been set up.
|
|
9
|
+
// Only shown in interactive terminals — suppressed in pipes and after gji init --write.
|
|
10
|
+
const isMetaArg = argv[0] === 'init'
|
|
11
|
+
|| argv[0] === '--version' || argv[0] === '-V'
|
|
12
|
+
|| argv[0] === '--help' || argv[0] === '-h';
|
|
13
|
+
if (process.stderr.isTTY === true && !isMetaArg) {
|
|
14
|
+
await warnIfMissingShellIntegration();
|
|
15
|
+
}
|
|
16
|
+
const result = await runCli(argv, {
|
|
6
17
|
stderr: (chunk) => process.stderr.write(chunk),
|
|
7
18
|
stdout: (chunk) => process.stdout.write(chunk),
|
|
8
19
|
});
|
|
@@ -14,4 +25,17 @@ async function main() {
|
|
|
14
25
|
process.exitCode = 1;
|
|
15
26
|
}
|
|
16
27
|
}
|
|
28
|
+
async function warnIfMissingShellIntegration() {
|
|
29
|
+
try {
|
|
30
|
+
const { config } = await loadGlobalConfig(homedir());
|
|
31
|
+
if (!config.shellIntegration) {
|
|
32
|
+
const shellBin = (process.env.SHELL ?? '').split('/').at(-1);
|
|
33
|
+
const shellArg = shellBin && ['bash', 'zsh', 'fish'].includes(shellBin) ? ` ${shellBin}` : '';
|
|
34
|
+
process.stderr.write(`gji: shell integration not set up — run \`gji init${shellArg} --write\` to enable automatic cd.\n`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
// best-effort; never block the command
|
|
39
|
+
}
|
|
40
|
+
}
|
|
17
41
|
void main();
|
package/dist/init.d.ts
CHANGED
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
export type SupportedShell = 'bash' | 'fish' | 'zsh';
|
|
2
2
|
export type InstallSaveTarget = 'local' | 'global';
|
|
3
|
+
export interface SetupWizardResult {
|
|
4
|
+
branchPrefix?: string;
|
|
5
|
+
hooks?: {
|
|
6
|
+
afterCreate?: string;
|
|
7
|
+
afterEnter?: string;
|
|
8
|
+
beforeRemove?: string;
|
|
9
|
+
};
|
|
10
|
+
installSaveTarget: InstallSaveTarget;
|
|
11
|
+
worktreePath?: string;
|
|
12
|
+
}
|
|
3
13
|
export interface InitCommandOptions {
|
|
4
14
|
cwd: string;
|
|
5
15
|
home?: string;
|
|
6
|
-
|
|
16
|
+
promptForSetup?: () => Promise<SetupWizardResult | null>;
|
|
7
17
|
shell?: string;
|
|
8
18
|
stderr?: (chunk: string) => void;
|
|
9
19
|
stdout: (chunk: string) => void;
|
package/dist/init.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
2
2
|
import { homedir } from 'node:os';
|
|
3
3
|
import { dirname, join } from 'node:path';
|
|
4
|
-
import { isCancel, select } from '@clack/prompts';
|
|
5
|
-
import { loadGlobalConfig, updateGlobalConfigKey } from './config.js';
|
|
4
|
+
import { intro, isCancel, outro, select, text } from '@clack/prompts';
|
|
5
|
+
import { loadConfig, loadGlobalConfig, saveGlobalConfig, saveLocalConfig, updateGlobalConfigKey } from './config.js';
|
|
6
6
|
const START_MARKER = '# >>> gji init >>>';
|
|
7
7
|
const END_MARKER = '# <<< gji init <<<';
|
|
8
8
|
const SHELL_WRAPPED_COMMANDS = [
|
|
@@ -60,19 +60,21 @@ export async function runInitCommand(options) {
|
|
|
60
60
|
const next = upsertShellIntegration(current, script);
|
|
61
61
|
await writeFile(rcPath, next, 'utf8');
|
|
62
62
|
options.stdout(`${rcPath}\n`);
|
|
63
|
-
//
|
|
64
|
-
// Skip if already configured. When using the default interactive prompt, also
|
|
65
|
-
// require a real TTY so we don't block in piped/headless environments.
|
|
63
|
+
// Run the setup wizard on the first-ever init (not on subsequent re-runs).
|
|
66
64
|
const { config: globalConfig } = await loadGlobalConfig(home);
|
|
67
|
-
const
|
|
65
|
+
const alreadyConfigured = 'shellIntegration' in globalConfig || 'installSaveTarget' in globalConfig;
|
|
66
|
+
const hasCustomPrompt = options.promptForSetup !== undefined;
|
|
68
67
|
const canPrompt = hasCustomPrompt || process.stdout.isTTY === true;
|
|
69
|
-
if (!
|
|
70
|
-
const prompt = options.
|
|
71
|
-
const
|
|
72
|
-
if (
|
|
73
|
-
await updateGlobalConfigKey('installSaveTarget',
|
|
68
|
+
if (!alreadyConfigured && canPrompt) {
|
|
69
|
+
const prompt = options.promptForSetup ?? defaultPromptForSetup;
|
|
70
|
+
const result = await prompt();
|
|
71
|
+
if (result) {
|
|
72
|
+
await updateGlobalConfigKey('installSaveTarget', result.installSaveTarget, home);
|
|
73
|
+
await saveWizardConfig(result, options.cwd, home);
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
|
+
// Mark shell integration as installed so the first-run nudge is suppressed.
|
|
77
|
+
await updateGlobalConfigKey('shellIntegration', true, home);
|
|
76
78
|
return 0;
|
|
77
79
|
}
|
|
78
80
|
export function renderShellIntegration(shell) {
|
|
@@ -111,6 +113,32 @@ export function upsertShellIntegration(existingConfig, script) {
|
|
|
111
113
|
}
|
|
112
114
|
return ensureTrailingNewline(`${prefix}\n\n${trimmedScript}`);
|
|
113
115
|
}
|
|
116
|
+
async function saveWizardConfig(result, cwd, home) {
|
|
117
|
+
const values = {};
|
|
118
|
+
if (result.branchPrefix)
|
|
119
|
+
values.branchPrefix = result.branchPrefix;
|
|
120
|
+
if (result.worktreePath)
|
|
121
|
+
values.worktreePath = result.worktreePath;
|
|
122
|
+
const hooks = {};
|
|
123
|
+
if (result.hooks?.afterCreate)
|
|
124
|
+
hooks.afterCreate = result.hooks.afterCreate;
|
|
125
|
+
if (result.hooks?.afterEnter)
|
|
126
|
+
hooks.afterEnter = result.hooks.afterEnter;
|
|
127
|
+
if (result.hooks?.beforeRemove)
|
|
128
|
+
hooks.beforeRemove = result.hooks.beforeRemove;
|
|
129
|
+
if (Object.keys(hooks).length > 0)
|
|
130
|
+
values.hooks = hooks;
|
|
131
|
+
if (Object.keys(values).length === 0)
|
|
132
|
+
return;
|
|
133
|
+
if (result.installSaveTarget === 'local') {
|
|
134
|
+
const loaded = await loadConfig(cwd);
|
|
135
|
+
await saveLocalConfig(cwd, { ...loaded.config, ...values });
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
const { config: existing } = await loadGlobalConfig(home);
|
|
139
|
+
await saveGlobalConfig({ ...existing, ...values }, home);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
114
142
|
function resolveShell(requestedShell, detectedShell) {
|
|
115
143
|
const requested = normalizeShell(requestedShell);
|
|
116
144
|
if (requested) {
|
|
@@ -211,16 +239,71 @@ function indentBlock(value, spaces) {
|
|
|
211
239
|
.map((line) => line.length === 0 ? '' : `${prefix}${line}`)
|
|
212
240
|
.join('\n');
|
|
213
241
|
}
|
|
214
|
-
async function
|
|
215
|
-
|
|
216
|
-
|
|
242
|
+
async function defaultPromptForSetup() {
|
|
243
|
+
intro('gji setup');
|
|
244
|
+
const installSaveTarget = await select({
|
|
245
|
+
message: 'Where should preferences be saved?',
|
|
217
246
|
options: [
|
|
218
|
-
{ value: '
|
|
219
|
-
{ value: '
|
|
247
|
+
{ value: 'global', label: '~/.config/gji/config.json', hint: 'personal — never committed' },
|
|
248
|
+
{ value: 'local', label: '.gji.json', hint: 'repo — committed with the project' },
|
|
220
249
|
],
|
|
221
250
|
});
|
|
222
|
-
if (isCancel(
|
|
251
|
+
if (isCancel(installSaveTarget)) {
|
|
252
|
+
outro('Setup skipped.');
|
|
253
|
+
return null;
|
|
254
|
+
}
|
|
255
|
+
const branchPrefix = await text({
|
|
256
|
+
message: 'Default branch prefix?',
|
|
257
|
+
placeholder: 'e.g. feat/ or fix/ — leave blank to skip',
|
|
258
|
+
});
|
|
259
|
+
if (isCancel(branchPrefix)) {
|
|
260
|
+
outro('Setup skipped.');
|
|
261
|
+
return null;
|
|
262
|
+
}
|
|
263
|
+
const worktreePath = await text({
|
|
264
|
+
message: 'Worktree base path?',
|
|
265
|
+
placeholder: 'leave blank to use the default path',
|
|
266
|
+
});
|
|
267
|
+
if (isCancel(worktreePath)) {
|
|
268
|
+
outro('Setup skipped.');
|
|
269
|
+
return null;
|
|
270
|
+
}
|
|
271
|
+
const afterCreate = await text({
|
|
272
|
+
message: 'afterCreate hook — run after creating a worktree?',
|
|
273
|
+
placeholder: 'e.g. pnpm install — leave blank to skip',
|
|
274
|
+
});
|
|
275
|
+
if (isCancel(afterCreate)) {
|
|
276
|
+
outro('Setup skipped.');
|
|
277
|
+
return null;
|
|
278
|
+
}
|
|
279
|
+
const afterEnter = await text({
|
|
280
|
+
message: 'afterEnter hook — run after entering a worktree?',
|
|
281
|
+
placeholder: 'e.g. nvm use — leave blank to skip',
|
|
282
|
+
});
|
|
283
|
+
if (isCancel(afterEnter)) {
|
|
284
|
+
outro('Setup skipped.');
|
|
285
|
+
return null;
|
|
286
|
+
}
|
|
287
|
+
const beforeRemove = await text({
|
|
288
|
+
message: 'beforeRemove hook — run before removing a worktree?',
|
|
289
|
+
placeholder: 'leave blank to skip',
|
|
290
|
+
});
|
|
291
|
+
if (isCancel(beforeRemove)) {
|
|
292
|
+
outro('Setup skipped.');
|
|
223
293
|
return null;
|
|
224
294
|
}
|
|
225
|
-
|
|
295
|
+
outro('Setup complete!');
|
|
296
|
+
const hooks = {};
|
|
297
|
+
if (afterCreate)
|
|
298
|
+
hooks.afterCreate = afterCreate;
|
|
299
|
+
if (afterEnter)
|
|
300
|
+
hooks.afterEnter = afterEnter;
|
|
301
|
+
if (beforeRemove)
|
|
302
|
+
hooks.beforeRemove = beforeRemove;
|
|
303
|
+
return {
|
|
304
|
+
branchPrefix: branchPrefix || undefined,
|
|
305
|
+
hooks: Object.keys(hooks).length > 0 ? hooks : undefined,
|
|
306
|
+
installSaveTarget,
|
|
307
|
+
worktreePath: worktreePath || undefined,
|
|
308
|
+
};
|
|
226
309
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
.TH GJI\-CLEAN 1 "April 2026" "gji 0.4.0" "User Commands"
|
|
2
|
+
.SH NAME
|
|
3
|
+
gji\-clean \- interactively prune linked worktrees
|
|
4
|
+
.SH SYNOPSIS
|
|
5
|
+
.B gji clean [\fIoptions\fR] [options]
|
|
6
|
+
.SH DESCRIPTION
|
|
7
|
+
interactively prune linked worktrees
|
|
8
|
+
.SH OPTIONS
|
|
9
|
+
.TP
|
|
10
|
+
.B \-f, \-\-force
|
|
11
|
+
bypass prompts, force\-remove dirty worktrees, and force\-delete unmerged branches
|
|
12
|
+
.TP
|
|
13
|
+
.B \-\-dry\-run
|
|
14
|
+
show what would be deleted without removing anything
|
|
15
|
+
.TP
|
|
16
|
+
.B \-\-json
|
|
17
|
+
emit JSON on success or error instead of human\-readable output
|
|
18
|
+
.SH "SEE ALSO"
|
|
19
|
+
.BR gji (1)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
.TH GJI\-CONFIG 1 "April 2026" "gji 0.4.0" "User Commands"
|
|
2
|
+
.SH NAME
|
|
3
|
+
gji\-config \- manage global config defaults
|
|
4
|
+
.SH SYNOPSIS
|
|
5
|
+
.B gji config [options] [command]
|
|
6
|
+
.SH DESCRIPTION
|
|
7
|
+
manage global config defaults
|
|
8
|
+
.SH SUBCOMMANDS
|
|
9
|
+
.TP
|
|
10
|
+
.B get
|
|
11
|
+
print the global config or a single key
|
|
12
|
+
.TP
|
|
13
|
+
.B set
|
|
14
|
+
set a global config value
|
|
15
|
+
.TP
|
|
16
|
+
.B unset
|
|
17
|
+
remove a global config value
|
|
18
|
+
.SH "SEE ALSO"
|
|
19
|
+
.BR gji (1)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
.TH GJI\-GO 1 "April 2026" "gji 0.4.0" "User Commands"
|
|
2
|
+
.SH NAME
|
|
3
|
+
gji\-go \- print or select a worktree path
|
|
4
|
+
.SH SYNOPSIS
|
|
5
|
+
.B gji go [\fIoptions\fR] [options] [branch]
|
|
6
|
+
.SH DESCRIPTION
|
|
7
|
+
print or select a worktree path
|
|
8
|
+
.SH OPTIONS
|
|
9
|
+
.TP
|
|
10
|
+
.B \-\-print
|
|
11
|
+
print the resolved worktree path explicitly
|
|
12
|
+
.SH "SEE ALSO"
|
|
13
|
+
.BR gji (1)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
.TH GJI\-INIT 1 "April 2026" "gji 0.4.0" "User Commands"
|
|
2
|
+
.SH NAME
|
|
3
|
+
gji\-init \- print or install shell integration
|
|
4
|
+
.SH SYNOPSIS
|
|
5
|
+
.B gji init [\fIoptions\fR] [options] [shell]
|
|
6
|
+
.SH DESCRIPTION
|
|
7
|
+
print or install shell integration
|
|
8
|
+
.SH OPTIONS
|
|
9
|
+
.TP
|
|
10
|
+
.B \-\-write
|
|
11
|
+
write the integration to the shell config file
|
|
12
|
+
.SH "SEE ALSO"
|
|
13
|
+
.BR gji (1)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
.TH GJI\-LS 1 "April 2026" "gji 0.4.0" "User Commands"
|
|
2
|
+
.SH NAME
|
|
3
|
+
gji\-ls \- list active worktrees
|
|
4
|
+
.SH SYNOPSIS
|
|
5
|
+
.B gji ls [\fIoptions\fR] [options]
|
|
6
|
+
.SH DESCRIPTION
|
|
7
|
+
list active worktrees
|
|
8
|
+
.SH OPTIONS
|
|
9
|
+
.TP
|
|
10
|
+
.B \-\-json
|
|
11
|
+
print active worktrees as JSON
|
|
12
|
+
.SH "SEE ALSO"
|
|
13
|
+
.BR gji (1)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
.TH GJI\-NEW 1 "April 2026" "gji 0.4.0" "User Commands"
|
|
2
|
+
.SH NAME
|
|
3
|
+
gji\-new \- create a new branch or detached linked worktree
|
|
4
|
+
.SH SYNOPSIS
|
|
5
|
+
.B gji new [\fIoptions\fR] [options] [branch]
|
|
6
|
+
.SH DESCRIPTION
|
|
7
|
+
create a new branch or detached linked worktree
|
|
8
|
+
.SH OPTIONS
|
|
9
|
+
.TP
|
|
10
|
+
.B \-f, \-\-force
|
|
11
|
+
remove and recreate the worktree if the target path already exists
|
|
12
|
+
.TP
|
|
13
|
+
.B \-\-detached
|
|
14
|
+
create a detached worktree without a branch
|
|
15
|
+
.TP
|
|
16
|
+
.B \-\-dry\-run
|
|
17
|
+
show what would be created without executing any git commands or writing files
|
|
18
|
+
.TP
|
|
19
|
+
.B \-\-json
|
|
20
|
+
emit JSON on success or error instead of human\-readable output
|
|
21
|
+
.SH "SEE ALSO"
|
|
22
|
+
.BR gji (1)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
.TH GJI\-PR 1 "April 2026" "gji 0.4.0" "User Commands"
|
|
2
|
+
.SH NAME
|
|
3
|
+
gji\-pr \- fetch a pull request by number, #number, or URL into a linked worktree
|
|
4
|
+
.SH SYNOPSIS
|
|
5
|
+
.B gji pr [\fIoptions\fR] [options] <ref>
|
|
6
|
+
.SH DESCRIPTION
|
|
7
|
+
fetch a pull request by number, #number, or URL into a linked worktree
|
|
8
|
+
.SH OPTIONS
|
|
9
|
+
.TP
|
|
10
|
+
.B \-\-dry\-run
|
|
11
|
+
show what would be created without executing any git commands or writing files
|
|
12
|
+
.TP
|
|
13
|
+
.B \-\-json
|
|
14
|
+
emit JSON on success or error instead of human\-readable output
|
|
15
|
+
.SH "SEE ALSO"
|
|
16
|
+
.BR gji (1)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
.TH GJI\-REMOVE 1 "April 2026" "gji 0.4.0" "User Commands"
|
|
2
|
+
.SH NAME
|
|
3
|
+
gji\-remove \- remove a linked worktree and delete its branch when present
|
|
4
|
+
.SH SYNOPSIS
|
|
5
|
+
.B gji remove [\fIoptions\fR] [options] [branch]
|
|
6
|
+
.SH DESCRIPTION
|
|
7
|
+
remove a linked worktree and delete its branch when present
|
|
8
|
+
.SH OPTIONS
|
|
9
|
+
.TP
|
|
10
|
+
.B \-f, \-\-force
|
|
11
|
+
bypass prompts, force\-remove a dirty worktree, and force\-delete an unmerged branch
|
|
12
|
+
.TP
|
|
13
|
+
.B \-\-dry\-run
|
|
14
|
+
show what would be deleted without removing anything
|
|
15
|
+
.TP
|
|
16
|
+
.B \-\-json
|
|
17
|
+
emit JSON on success or error instead of human\-readable output
|
|
18
|
+
.SH "SEE ALSO"
|
|
19
|
+
.BR gji (1)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
.TH GJI\-ROOT 1 "April 2026" "gji 0.4.0" "User Commands"
|
|
2
|
+
.SH NAME
|
|
3
|
+
gji\-root \- print the main repository root path
|
|
4
|
+
.SH SYNOPSIS
|
|
5
|
+
.B gji root [\fIoptions\fR] [options]
|
|
6
|
+
.SH DESCRIPTION
|
|
7
|
+
print the main repository root path
|
|
8
|
+
.SH OPTIONS
|
|
9
|
+
.TP
|
|
10
|
+
.B \-\-print
|
|
11
|
+
print the resolved repository root path explicitly
|
|
12
|
+
.SH "SEE ALSO"
|
|
13
|
+
.BR gji (1)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
.TH GJI\-STATUS 1 "April 2026" "gji 0.4.0" "User Commands"
|
|
2
|
+
.SH NAME
|
|
3
|
+
gji\-status \- summarize repository and worktree health
|
|
4
|
+
.SH SYNOPSIS
|
|
5
|
+
.B gji status [\fIoptions\fR] [options]
|
|
6
|
+
.SH DESCRIPTION
|
|
7
|
+
summarize repository and worktree health
|
|
8
|
+
.SH OPTIONS
|
|
9
|
+
.TP
|
|
10
|
+
.B \-\-json
|
|
11
|
+
print repository and worktree health as JSON
|
|
12
|
+
.SH "SEE ALSO"
|
|
13
|
+
.BR gji (1)
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
.TH GJI\-SYNC 1 "April 2026" "gji 0.4.0" "User Commands"
|
|
2
|
+
.SH NAME
|
|
3
|
+
gji\-sync \- fetch and update one or all worktrees
|
|
4
|
+
.SH SYNOPSIS
|
|
5
|
+
.B gji sync [\fIoptions\fR] [options]
|
|
6
|
+
.SH DESCRIPTION
|
|
7
|
+
fetch and update one or all worktrees
|
|
8
|
+
.SH OPTIONS
|
|
9
|
+
.TP
|
|
10
|
+
.B \-\-all
|
|
11
|
+
sync every worktree in the repository
|
|
12
|
+
.TP
|
|
13
|
+
.B \-\-json
|
|
14
|
+
emit JSON on success or error instead of human\-readable output
|
|
15
|
+
.SH "SEE ALSO"
|
|
16
|
+
.BR gji (1)
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
.TH GJI\-TRIGGER\-HOOK 1 "April 2026" "gji 0.4.0" "User Commands"
|
|
2
|
+
.SH NAME
|
|
3
|
+
gji\-trigger\-hook \- run a named hook (afterCreate, afterEnter, beforeRemove) in the current worktree
|
|
4
|
+
.SH SYNOPSIS
|
|
5
|
+
.B gji trigger\-hook [options] <hook>
|
|
6
|
+
.SH DESCRIPTION
|
|
7
|
+
run a named hook (afterCreate, afterEnter, beforeRemove) in the current worktree
|
|
8
|
+
.SH "SEE ALSO"
|
|
9
|
+
.BR gji (1)
|
package/man/man1/gji.1
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
.TH GJI 1 "April 2026" "gji 0.4.0" "User Commands"
|
|
2
|
+
.SH NAME
|
|
3
|
+
gji \- Context switching without the mess.
|
|
4
|
+
.SH SYNOPSIS
|
|
5
|
+
.B gji
|
|
6
|
+
[\fIoptions\fR] <\fIcommand\fR> [\fIargs\fR]
|
|
7
|
+
.SH DESCRIPTION
|
|
8
|
+
Context switching without the mess.
|
|
9
|
+
.PP
|
|
10
|
+
Each branch lives in its own worktree with its own node_modules and terminal,
|
|
11
|
+
eliminating the need for \fBgit stash\fR when switching contexts.
|
|
12
|
+
.SH COMMANDS
|
|
13
|
+
.TP
|
|
14
|
+
.B new [options] [branch]
|
|
15
|
+
create a new branch or detached linked worktree
|
|
16
|
+
.TP
|
|
17
|
+
.B init [options] [shell]
|
|
18
|
+
print or install shell integration
|
|
19
|
+
.TP
|
|
20
|
+
.B pr [options] <ref>
|
|
21
|
+
fetch a pull request by number, #number, or URL into a linked worktree
|
|
22
|
+
.TP
|
|
23
|
+
.B go [options] [branch]
|
|
24
|
+
print or select a worktree path
|
|
25
|
+
.TP
|
|
26
|
+
.B root [options]
|
|
27
|
+
print the main repository root path
|
|
28
|
+
.TP
|
|
29
|
+
.B status [options]
|
|
30
|
+
summarize repository and worktree health
|
|
31
|
+
.TP
|
|
32
|
+
.B sync [options]
|
|
33
|
+
fetch and update one or all worktrees
|
|
34
|
+
.TP
|
|
35
|
+
.B ls [options]
|
|
36
|
+
list active worktrees
|
|
37
|
+
.TP
|
|
38
|
+
.B clean [options]
|
|
39
|
+
interactively prune linked worktrees
|
|
40
|
+
.TP
|
|
41
|
+
.B remove [options] [branch]
|
|
42
|
+
remove a linked worktree and delete its branch when present
|
|
43
|
+
.br
|
|
44
|
+
Alias: \fBrm\fR
|
|
45
|
+
.TP
|
|
46
|
+
.B trigger\-hook [options] <hook>
|
|
47
|
+
run a named hook (afterCreate, afterEnter, beforeRemove) in the current worktree
|
|
48
|
+
.TP
|
|
49
|
+
.B config [options] [command]
|
|
50
|
+
manage global config defaults
|
|
51
|
+
.SH OPTIONS
|
|
52
|
+
.TP
|
|
53
|
+
.B \-V, \-\-version
|
|
54
|
+
output the version number
|
|
55
|
+
.SH "SEE ALSO"
|
|
56
|
+
.BR gji\-new (1),
|
|
57
|
+
.BR gji\-init (1),
|
|
58
|
+
.BR gji\-pr (1),
|
|
59
|
+
.BR gji\-go (1),
|
|
60
|
+
.BR gji\-root (1),
|
|
61
|
+
.BR gji\-status (1),
|
|
62
|
+
.BR gji\-sync (1),
|
|
63
|
+
.BR gji\-ls (1),
|
|
64
|
+
.BR gji\-clean (1),
|
|
65
|
+
.BR gji\-remove (1),
|
|
66
|
+
.BR gji\-trigger\-hook (1),
|
|
67
|
+
.BR gji\-config (1)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solaqua/gji",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Git worktree CLI for fast context switching.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "sjquant",
|
|
@@ -24,9 +24,13 @@
|
|
|
24
24
|
],
|
|
25
25
|
"files": [
|
|
26
26
|
"dist",
|
|
27
|
+
"man",
|
|
27
28
|
"README.md",
|
|
28
29
|
"LICENSE"
|
|
29
30
|
],
|
|
31
|
+
"man": [
|
|
32
|
+
"man/man1/gji.1"
|
|
33
|
+
],
|
|
30
34
|
"publishConfig": {
|
|
31
35
|
"access": "public"
|
|
32
36
|
},
|
|
@@ -38,7 +42,8 @@
|
|
|
38
42
|
},
|
|
39
43
|
"scripts": {
|
|
40
44
|
"build": "node scripts/clean-dist.mjs && tsc -p tsconfig.build.json",
|
|
41
|
-
"
|
|
45
|
+
"generate-man": "node scripts/generate-man.mjs",
|
|
46
|
+
"prepublishOnly": "pnpm test && pnpm build && pnpm generate-man",
|
|
42
47
|
"test": "vitest run --passWithNoTests",
|
|
43
48
|
"test:watch": "vitest"
|
|
44
49
|
},
|