@solaqua/gji 0.9.0 → 0.10.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/README.md CHANGED
@@ -107,8 +107,9 @@ gji status
107
107
  gji go feature/dark-mode
108
108
  gji go main
109
109
 
110
- # open any worktree in an editor (interactive picker)
110
+ # open the current worktree in an editor
111
111
  gji open
112
+ gji open --select # choose another worktree interactively
112
113
  gji open feature/dark-mode --editor code
113
114
 
114
115
  # clean up when done
@@ -127,6 +128,7 @@ Set `worktreePath` in your config to use a different base (e.g. `"~/worktrees"`
127
128
 
128
129
  ```sh
129
130
  gji new feature/auth-refactor # new branch + worktree
131
+ gji new feature/auth-tests --from-current # branch from the current worktree
130
132
  gji new --detached # scratch space, auto-named
131
133
 
132
134
  gji pr 1234 # checkout PR locally
@@ -229,10 +231,10 @@ path=$(gji root --print)
229
231
 
230
232
  | Command | Description |
231
233
  |---|---|
232
- | `gji new [branch] [--detached] [--open] [--editor <cli>] [--json]` | create branch + worktree, cd in (validates branch name against Git rules) |
234
+ | `gji new [branch] [--from-current] [--detached] [--open] [--editor <cli>] [--json]` | create branch + worktree, optionally based on the current worktree |
233
235
  | `gji pr <ref> [--json]` | fetch PR ref, create worktree, cd in |
234
236
  | `gji pr open [branch|#N] [--select]` | open the current worktree PR, or choose a linked worktree with `--select` |
235
- | `gji open [branch] [--editor <cli>] [--save] [--workspace]` | open a worktree in an editor |
237
+ | `gji open [branch] [--select] [--editor <cli>] [--save] [--workspace]` | open the current or selected worktree in an editor |
236
238
  | `gji go [branch] [--print]` | jump to a worktree |
237
239
  | `gji root [--print]` | jump to the main repo root |
238
240
  | `gji status [--json]` | repo overview, worktree health, ahead/behind |
package/dist/cli.js CHANGED
@@ -120,6 +120,7 @@ function registerCommands(program) {
120
120
  .description("create a new branch or detached linked worktree")
121
121
  .option("-f, --force", "remove and recreate the worktree if the target path already exists")
122
122
  .option("--detached", "create a detached worktree without a branch")
123
+ .option("--from-current", "base the new branch on the current worktree instead of the main worktree (cannot be combined with --detached)")
123
124
  .option("--open", "open the new worktree in an editor after creation")
124
125
  .option("--editor <cli>", "editor CLI to use with --open (code, cursor, zed, …)")
125
126
  .option("--dry-run", "show what would be created without executing any git commands or writing files")
@@ -167,6 +168,7 @@ function registerCommands(program) {
167
168
  program
168
169
  .command("open [branch]")
169
170
  .description("open the worktree in an editor")
171
+ .option("--select", "choose a worktree with the interactive selector")
170
172
  .option("--editor <cli>", "editor CLI to use (code, cursor, zed, windsurf, subl, …)")
171
173
  .option("--save", "save the chosen editor to global config")
172
174
  .option("--workspace", "generate a .code-workspace file before opening (VS Code / Cursor / Windsurf)")
@@ -277,6 +279,7 @@ function attachCommandActions(program, options) {
277
279
  detached: commandOptions.detached,
278
280
  dryRun: commandOptions.dryRun,
279
281
  editor: commandOptions.editor,
282
+ fromCurrent: commandOptions.fromCurrent,
280
283
  force: commandOptions.force,
281
284
  json: commandOptions.json,
282
285
  open: commandOptions.open,
@@ -397,6 +400,7 @@ function attachCommandActions(program, options) {
397
400
  cwd: options.cwd,
398
401
  editor: commandOptions.editor,
399
402
  save: commandOptions.save,
403
+ select: commandOptions.select,
400
404
  stderr: options.stderr,
401
405
  stdout: options.stdout,
402
406
  workspace: commandOptions.workspace,
@@ -16060,7 +16060,7 @@ _gji_completion() {
16060
16060
 
16061
16061
  case "$command_name" in
16062
16062
  new)
16063
- COMPREPLY=( $(compgen -W "--detached --force --open --editor --dry-run --json --help" -- "$cur") )
16063
+ COMPREPLY=( $(compgen -W "--detached --from-current --force --open --editor --dry-run --json --help" -- "$cur") )
16064
16064
  ;;
16065
16065
  init)
16066
16066
  COMPREPLY=( $(compgen -W "${shells} --write --json --help" -- "$cur") )
@@ -16102,7 +16102,7 @@ _gji_completion() {
16102
16102
  COMPREPLY=( $(compgen -W "--json --help" -- "$cur") )
16103
16103
  ;;
16104
16104
  open)
16105
- COMPREPLY=( $(compgen -W "$(__gji_worktree_branches) --editor --save --workspace --help" -- "$cur") )
16105
+ COMPREPLY=( $(compgen -W "$(__gji_worktree_branches) --editor --select --save --workspace --help" -- "$cur") )
16106
16106
  ;;
16107
16107
  go|jump)
16108
16108
  COMPREPLY=( $(compgen -W "$(__gji_worktree_branches) --print --help" -- "$cur") )
@@ -16297,6 +16297,7 @@ complete -c gji -f
16297
16297
  ${commandLines}
16298
16298
 
16299
16299
  complete -c gji -n '__fish_seen_subcommand_from new' -l detached -d 'create a detached worktree without a branch'
16300
+ complete -c gji -n '__fish_seen_subcommand_from new' -l from-current -d 'base the new branch on the current worktree instead of the main worktree'
16300
16301
  complete -c gji -n '__fish_seen_subcommand_from new' -l force -d 'remove and recreate the worktree if the target path already exists'
16301
16302
  complete -c gji -n '__fish_seen_subcommand_from new' -l open -d 'open the new worktree in an editor after creation'
16302
16303
  complete -c gji -n '__fish_seen_subcommand_from new' -l editor -r -d 'editor CLI to use with --open (code, cursor, zed, \u2026)'
@@ -16326,6 +16327,7 @@ complete -c gji -n '__fish_seen_subcommand_from back' -l print -d 'print the res
16326
16327
  complete -c gji -n '__fish_seen_subcommand_from history' -l json -d 'print history as JSON'
16327
16328
 
16328
16329
  complete -c gji -n '__fish_seen_subcommand_from open' -l editor -r -d 'editor CLI to use (code, cursor, zed, windsurf, subl, \u2026)'
16330
+ complete -c gji -n '__fish_seen_subcommand_from open' -l select -d 'choose a worktree with the interactive selector'
16329
16331
  complete -c gji -n '__fish_seen_subcommand_from open' -l save -d 'save the chosen editor to global config'
16330
16332
  complete -c gji -n '__fish_seen_subcommand_from open' -l workspace -d 'generate a .code-workspace file before opening (VS Code / Cursor / Windsurf)'
16331
16333
  complete -c gji -n '__fish_seen_subcommand_from open' -a '(__gji_worktree_branches)' -d 'worktree branch'
@@ -16451,7 +16453,7 @@ fi
16451
16453
 
16452
16454
  case "\${words[2]}" in
16453
16455
  new)
16454
- _arguments '--detached[create a detached worktree without a branch]' '--force[remove and recreate the worktree if the target path already exists]' '--open[open the new worktree in an editor after creation]' '--editor[editor CLI to use with --open (code, cursor, zed, \u2026)]:editor:' '--dry-run[show what would be created without executing any git commands or writing files]' '--json[emit JSON on success or error instead of human-readable output]' '2:branch: '
16456
+ _arguments '--detached[create a detached worktree without a branch]' '--from-current[base the new branch on the current worktree instead of the main worktree]' '--force[remove and recreate the worktree if the target path already exists]' '--open[open the new worktree in an editor after creation]' '--editor[editor CLI to use with --open (code, cursor, zed, \u2026)]:editor:' '--dry-run[show what would be created without executing any git commands or writing files]' '--json[emit JSON on success or error instead of human-readable output]' '2:branch: '
16455
16457
  ;;
16456
16458
  init)
16457
16459
  _arguments '--write[write the integration to the shell config file]' '--json[emit a JSON error in non-interactive mode]' '2:shell:(${shells})'
@@ -16482,7 +16484,7 @@ case "\${words[2]}" in
16482
16484
  _arguments '--json[print history as JSON]'
16483
16485
  ;;
16484
16486
  open)
16485
- _arguments '--editor[editor CLI to use (code, cursor, zed, windsurf, subl, \u2026)]:editor:' '--save[save the chosen editor to global config]' '--workspace[generate a .code-workspace file before opening (VS Code / Cursor / Windsurf)]' '2:branch:->worktrees'
16487
+ _arguments '--editor[editor CLI to use (code, cursor, zed, windsurf, subl, \u2026)]:editor:' '--select[choose a worktree with the interactive selector]' '--save[save the chosen editor to global config]' '--workspace[generate a .code-workspace file before opening (VS Code / Cursor / Windsurf)]' '2:branch:->worktrees'
16486
16488
  ;;
16487
16489
  go|jump)
16488
16490
  _arguments '--print[print the resolved worktree path explicitly]' '2:branch:->worktrees'
@@ -17765,6 +17767,17 @@ function createNewCommand(dependencies = {}) {
17765
17767
  const prompt = dependencies.promptForPathConflict ?? promptForPathConflict;
17766
17768
  const spawnEditor = dependencies.spawnEditor ?? defaultSpawnEditor;
17767
17769
  return async function runNewCommand2(options) {
17770
+ if (options.detached && options.fromCurrent) {
17771
+ const message = "--from-current cannot be used with --detached";
17772
+ if (options.json) {
17773
+ options.stderr(`${JSON.stringify({ error: message }, null, 2)}
17774
+ `);
17775
+ } else {
17776
+ options.stderr(`gji new: ${message}
17777
+ `);
17778
+ }
17779
+ return 1;
17780
+ }
17768
17781
  const repository = await detectRepository(options.cwd);
17769
17782
  const config = await loadEffectiveConfig(
17770
17783
  repository.repoRoot,
@@ -17908,7 +17921,15 @@ function createNewCommand(dependencies = {}) {
17908
17921
  return 0;
17909
17922
  }
17910
17923
  await mkdir5(dirname7(worktreePath), { recursive: true });
17911
- const gitArgs = options.detached ? ["worktree", "add", "--detach", worktreePath] : await localBranchExists(repository.repoRoot, worktreeName) ? ["worktree", "add", worktreePath, worktreeName] : ["worktree", "add", "-b", worktreeName, worktreePath];
17924
+ const startPoint = options.fromCurrent && !options.detached ? await resolveCurrentWorktreeHead(options.cwd) : void 0;
17925
+ const gitArgs = options.detached ? ["worktree", "add", "--detach", worktreePath] : await localBranchExists(repository.repoRoot, worktreeName) ? ["worktree", "add", worktreePath, worktreeName] : [
17926
+ "worktree",
17927
+ "add",
17928
+ "-b",
17929
+ worktreeName,
17930
+ worktreePath,
17931
+ ...startPoint ? [startPoint] : []
17932
+ ];
17912
17933
  await execFileAsync5("git", gitArgs, { cwd: repository.repoRoot });
17913
17934
  const syncPatterns = Array.isArray(config.syncFiles) ? config.syncFiles.filter(
17914
17935
  (p2) => typeof p2 === "string"
@@ -18123,6 +18144,11 @@ async function localBranchExists(repoRoot, branchName) {
18123
18144
  return false;
18124
18145
  }
18125
18146
  }
18147
+ async function resolveCurrentWorktreeHead(cwd) {
18148
+ return execFileAsync5("git", ["rev-parse", "--verify", "HEAD"], { cwd }).then(
18149
+ ({ stdout: stdout2 }) => stdout2.trim()
18150
+ );
18151
+ }
18126
18152
  async function writeOutput(worktreePath, stdout2) {
18127
18153
  await writeShellOutput(NEW_OUTPUT_FILE_ENV, worktreePath, stdout2);
18128
18154
  }
@@ -19119,6 +19145,16 @@ function createOpenCommand(dependencies = {}) {
19119
19145
  const promptForWorktree2 = dependencies.promptForWorktree ?? defaultPromptForWorktree;
19120
19146
  const spawnEditor = dependencies.spawnEditor ?? defaultSpawnEditor;
19121
19147
  return async function runOpenCommand2(options) {
19148
+ if (options.select && options.branch !== void 0) {
19149
+ options.stderr("gji open: --select cannot be used with a branch\n");
19150
+ return 1;
19151
+ }
19152
+ if (options.select && isHeadless()) {
19153
+ options.stderr(
19154
+ "gji open --select: selector is unavailable in non-interactive mode (GJI_NO_TUI=1)\n"
19155
+ );
19156
+ return 1;
19157
+ }
19122
19158
  const [worktrees, repository] = await Promise.all([
19123
19159
  listWorktrees(options.cwd),
19124
19160
  detectRepository(options.cwd)
@@ -19144,9 +19180,13 @@ function createOpenCommand(dependencies = {}) {
19144
19180
  }
19145
19181
  targetPath = match.worktree.path;
19146
19182
  targetWorktree = match.worktree;
19147
- } else if (isHeadless()) {
19183
+ } else if (!options.select) {
19148
19184
  targetWorktree = worktrees.find((w2) => w2.isCurrent);
19149
- targetPath = targetWorktree?.path ?? options.cwd;
19185
+ if (!targetWorktree) {
19186
+ options.stderr("gji open: unable to identify the current worktree\n");
19187
+ return 1;
19188
+ }
19189
+ targetPath = targetWorktree.path;
19150
19190
  } else {
19151
19191
  const entries = await buildWorktreePromptEntries(
19152
19192
  worktrees.map((worktree) => ({
@@ -20602,7 +20642,10 @@ function registerCommands(program2) {
20602
20642
  program2.command("new [branch]").description("create a new branch or detached linked worktree").option(
20603
20643
  "-f, --force",
20604
20644
  "remove and recreate the worktree if the target path already exists"
20605
- ).option("--detached", "create a detached worktree without a branch").option("--open", "open the new worktree in an editor after creation").option(
20645
+ ).option("--detached", "create a detached worktree without a branch").option(
20646
+ "--from-current",
20647
+ "base the new branch on the current worktree instead of the main worktree (cannot be combined with --detached)"
20648
+ ).option("--open", "open the new worktree in an editor after creation").option(
20606
20649
  "--editor <cli>",
20607
20650
  "editor CLI to use with --open (code, cursor, zed, \u2026)"
20608
20651
  ).option(
@@ -20631,7 +20674,7 @@ function registerCommands(program2) {
20631
20674
  "navigate to the previously visited worktree, optionally N steps back"
20632
20675
  ).option("--print", "print the resolved worktree path explicitly").action(notImplemented("back"));
20633
20676
  program2.command("history").description("show navigation history").option("--json", "print history as JSON").action(notImplemented("history"));
20634
- program2.command("open [branch]").description("open the worktree in an editor").option(
20677
+ program2.command("open [branch]").description("open the worktree in an editor").option("--select", "choose a worktree with the interactive selector").option(
20635
20678
  "--editor <cli>",
20636
20679
  "editor CLI to use (code, cursor, zed, windsurf, subl, \u2026)"
20637
20680
  ).option("--save", "save the chosen editor to global config").option(
@@ -20691,6 +20734,7 @@ function attachCommandActions(program2, options) {
20691
20734
  detached: commandOptions2.detached,
20692
20735
  dryRun: commandOptions2.dryRun,
20693
20736
  editor: commandOptions2.editor,
20737
+ fromCurrent: commandOptions2.fromCurrent,
20694
20738
  force: commandOptions2.force,
20695
20739
  json: commandOptions2.json,
20696
20740
  open: commandOptions2.open
@@ -20808,6 +20852,7 @@ function attachCommandActions(program2, options) {
20808
20852
  cwd: options.cwd,
20809
20853
  editor: commandOptions2.editor,
20810
20854
  save: commandOptions2.save,
20855
+ select: commandOptions2.select,
20811
20856
  stderr: options.stderr,
20812
20857
  stdout: options.stdout,
20813
20858
  workspace: commandOptions2.workspace
package/dist/new.d.ts CHANGED
@@ -7,6 +7,7 @@ export interface NewCommandOptions {
7
7
  detached?: boolean;
8
8
  dryRun?: boolean;
9
9
  editor?: string;
10
+ fromCurrent?: boolean;
10
11
  force?: boolean;
11
12
  json?: boolean;
12
13
  open?: boolean;
package/dist/new.js CHANGED
@@ -21,6 +21,16 @@ export function createNewCommand(dependencies = {}) {
21
21
  const prompt = dependencies.promptForPathConflict ?? promptForPathConflict;
22
22
  const spawnEditor = dependencies.spawnEditor ?? defaultSpawnEditor;
23
23
  return async function runNewCommand(options) {
24
+ if (options.detached && options.fromCurrent) {
25
+ const message = "--from-current cannot be used with --detached";
26
+ if (options.json) {
27
+ options.stderr(`${JSON.stringify({ error: message }, null, 2)}\n`);
28
+ }
29
+ else {
30
+ options.stderr(`gji new: ${message}\n`);
31
+ }
32
+ return 1;
33
+ }
24
34
  const repository = await detectRepository(options.cwd);
25
35
  const config = await loadEffectiveConfig(repository.repoRoot, undefined, options.stderr);
26
36
  const usesGeneratedDetachedName = options.detached && options.branch === undefined;
@@ -141,11 +151,21 @@ export function createNewCommand(dependencies = {}) {
141
151
  return 0;
142
152
  }
143
153
  await mkdir(dirname(worktreePath), { recursive: true });
154
+ const startPoint = options.fromCurrent && !options.detached
155
+ ? await resolveCurrentWorktreeHead(options.cwd)
156
+ : undefined;
144
157
  const gitArgs = options.detached
145
158
  ? ["worktree", "add", "--detach", worktreePath]
146
159
  : (await localBranchExists(repository.repoRoot, worktreeName))
147
160
  ? ["worktree", "add", worktreePath, worktreeName]
148
- : ["worktree", "add", "-b", worktreeName, worktreePath];
161
+ : [
162
+ "worktree",
163
+ "add",
164
+ "-b",
165
+ worktreeName,
166
+ worktreePath,
167
+ ...(startPoint ? [startPoint] : []),
168
+ ];
149
169
  await execFileAsync("git", gitArgs, { cwd: repository.repoRoot });
150
170
  // Sync files from main worktree before afterCreate so synced files are available to install scripts.
151
171
  const syncPatterns = Array.isArray(config.syncFiles)
@@ -333,6 +353,9 @@ async function localBranchExists(repoRoot, branchName) {
333
353
  return false;
334
354
  }
335
355
  }
356
+ async function resolveCurrentWorktreeHead(cwd) {
357
+ return execFileAsync("git", ["rev-parse", "--verify", "HEAD"], { cwd }).then(({ stdout }) => stdout.trim());
358
+ }
336
359
  async function writeOutput(worktreePath, stdout) {
337
360
  await writeShellOutput(NEW_OUTPUT_FILE_ENV, worktreePath, stdout);
338
361
  }
package/dist/open.d.ts CHANGED
@@ -6,6 +6,7 @@ export interface OpenCommandOptions {
6
6
  cwd: string;
7
7
  editor?: string;
8
8
  save?: boolean;
9
+ select?: boolean;
9
10
  stderr: (chunk: string) => void;
10
11
  stdout: (chunk: string) => void;
11
12
  workspace?: boolean;
package/dist/open.js CHANGED
@@ -16,6 +16,14 @@ export function createOpenCommand(dependencies = {}) {
16
16
  const promptForWorktree = dependencies.promptForWorktree ?? defaultPromptForWorktree;
17
17
  const spawnEditor = dependencies.spawnEditor ?? defaultSpawnEditor;
18
18
  return async function runOpenCommand(options) {
19
+ if (options.select && options.branch !== undefined) {
20
+ options.stderr("gji open: --select cannot be used with a branch\n");
21
+ return 1;
22
+ }
23
+ if (options.select && isHeadless()) {
24
+ options.stderr("gji open --select: selector is unavailable in non-interactive mode (GJI_NO_TUI=1)\n");
25
+ return 1;
26
+ }
19
27
  const [worktrees, repository] = await Promise.all([
20
28
  listWorktrees(options.cwd),
21
29
  detectRepository(options.cwd),
@@ -36,9 +44,13 @@ export function createOpenCommand(dependencies = {}) {
36
44
  targetPath = match.worktree.path;
37
45
  targetWorktree = match.worktree;
38
46
  }
39
- else if (isHeadless()) {
47
+ else if (!options.select) {
40
48
  targetWorktree = worktrees.find((w) => w.isCurrent);
41
- targetPath = targetWorktree?.path ?? options.cwd;
49
+ if (!targetWorktree) {
50
+ options.stderr("gji open: unable to identify the current worktree\n");
51
+ return 1;
52
+ }
53
+ targetPath = targetWorktree.path;
42
54
  }
43
55
  else {
44
56
  const entries = await buildWorktreePromptEntries(worktrees.map((worktree) => ({
@@ -137,7 +137,7 @@ _gji_completion() {
137
137
 
138
138
  case "$command_name" in
139
139
  new)
140
- COMPREPLY=( $(compgen -W "--detached --force --open --editor --dry-run --json --help" -- "$cur") )
140
+ COMPREPLY=( $(compgen -W "--detached --from-current --force --open --editor --dry-run --json --help" -- "$cur") )
141
141
  ;;
142
142
  init)
143
143
  COMPREPLY=( $(compgen -W "${shells} --write --json --help" -- "$cur") )
@@ -179,7 +179,7 @@ _gji_completion() {
179
179
  COMPREPLY=( $(compgen -W "--json --help" -- "$cur") )
180
180
  ;;
181
181
  open)
182
- COMPREPLY=( $(compgen -W "$(__gji_worktree_branches) --editor --save --workspace --help" -- "$cur") )
182
+ COMPREPLY=( $(compgen -W "$(__gji_worktree_branches) --editor --select --save --workspace --help" -- "$cur") )
183
183
  ;;
184
184
  go|jump)
185
185
  COMPREPLY=( $(compgen -W "$(__gji_worktree_branches) --print --help" -- "$cur") )
@@ -364,6 +364,7 @@ complete -c gji -f
364
364
  ${commandLines}
365
365
 
366
366
  complete -c gji -n '__fish_seen_subcommand_from new' -l detached -d 'create a detached worktree without a branch'
367
+ complete -c gji -n '__fish_seen_subcommand_from new' -l from-current -d 'base the new branch on the current worktree instead of the main worktree'
367
368
  complete -c gji -n '__fish_seen_subcommand_from new' -l force -d 'remove and recreate the worktree if the target path already exists'
368
369
  complete -c gji -n '__fish_seen_subcommand_from new' -l open -d 'open the new worktree in an editor after creation'
369
370
  complete -c gji -n '__fish_seen_subcommand_from new' -l editor -r -d 'editor CLI to use with --open (code, cursor, zed, …)'
@@ -393,6 +394,7 @@ complete -c gji -n '__fish_seen_subcommand_from back' -l print -d 'print the res
393
394
  complete -c gji -n '__fish_seen_subcommand_from history' -l json -d 'print history as JSON'
394
395
 
395
396
  complete -c gji -n '__fish_seen_subcommand_from open' -l editor -r -d 'editor CLI to use (code, cursor, zed, windsurf, subl, …)'
397
+ complete -c gji -n '__fish_seen_subcommand_from open' -l select -d 'choose a worktree with the interactive selector'
396
398
  complete -c gji -n '__fish_seen_subcommand_from open' -l save -d 'save the chosen editor to global config'
397
399
  complete -c gji -n '__fish_seen_subcommand_from open' -l workspace -d 'generate a .code-workspace file before opening (VS Code / Cursor / Windsurf)'
398
400
  complete -c gji -n '__fish_seen_subcommand_from open' -a '(__gji_worktree_branches)' -d 'worktree branch'
@@ -516,7 +518,7 @@ fi
516
518
 
517
519
  case "\${words[2]}" in
518
520
  new)
519
- _arguments '--detached[create a detached worktree without a branch]' '--force[remove and recreate the worktree if the target path already exists]' '--open[open the new worktree in an editor after creation]' '--editor[editor CLI to use with --open (code, cursor, zed, …)]:editor:' '--dry-run[show what would be created without executing any git commands or writing files]' '--json[emit JSON on success or error instead of human-readable output]' '2:branch: '
521
+ _arguments '--detached[create a detached worktree without a branch]' '--from-current[base the new branch on the current worktree instead of the main worktree]' '--force[remove and recreate the worktree if the target path already exists]' '--open[open the new worktree in an editor after creation]' '--editor[editor CLI to use with --open (code, cursor, zed, …)]:editor:' '--dry-run[show what would be created without executing any git commands or writing files]' '--json[emit JSON on success or error instead of human-readable output]' '2:branch: '
520
522
  ;;
521
523
  init)
522
524
  _arguments '--write[write the integration to the shell config file]' '--json[emit a JSON error in non-interactive mode]' '2:shell:(${shells})'
@@ -547,7 +549,7 @@ case "\${words[2]}" in
547
549
  _arguments '--json[print history as JSON]'
548
550
  ;;
549
551
  open)
550
- _arguments '--editor[editor CLI to use (code, cursor, zed, windsurf, subl, …)]:editor:' '--save[save the chosen editor to global config]' '--workspace[generate a .code-workspace file before opening (VS Code / Cursor / Windsurf)]' '2:branch:->worktrees'
552
+ _arguments '--editor[editor CLI to use (code, cursor, zed, windsurf, subl, …)]:editor:' '--select[choose a worktree with the interactive selector]' '--save[save the chosen editor to global config]' '--workspace[generate a .code-workspace file before opening (VS Code / Cursor / Windsurf)]' '2:branch:->worktrees'
551
553
  ;;
552
554
  go|jump)
553
555
  _arguments '--print[print the resolved worktree path explicitly]' '2:branch:->worktrees'
@@ -1,4 +1,4 @@
1
- .TH GJI\-BACK 1 "July 2026" "gji 0.9.0" "User Commands"
1
+ .TH GJI\-BACK 1 "July 2026" "gji 0.10.0" "User Commands"
2
2
  .SH NAME
3
3
  gji\-back \- navigate to the previously visited worktree, optionally N steps back
4
4
  .SH SYNOPSIS
@@ -1,4 +1,4 @@
1
- .TH GJI\-CLEAN 1 "July 2026" "gji 0.9.0" "User Commands"
1
+ .TH GJI\-CLEAN 1 "July 2026" "gji 0.10.0" "User Commands"
2
2
  .SH NAME
3
3
  gji\-clean \- interactively prune linked worktrees
4
4
  .SH SYNOPSIS
@@ -1,4 +1,4 @@
1
- .TH GJI\-COMPLETION 1 "July 2026" "gji 0.9.0" "User Commands"
1
+ .TH GJI\-COMPLETION 1 "July 2026" "gji 0.10.0" "User Commands"
2
2
  .SH NAME
3
3
  gji\-completion \- print shell completion definitions
4
4
  .SH SYNOPSIS
@@ -1,4 +1,4 @@
1
- .TH GJI\-CONFIG 1 "July 2026" "gji 0.9.0" "User Commands"
1
+ .TH GJI\-CONFIG 1 "July 2026" "gji 0.10.0" "User Commands"
2
2
  .SH NAME
3
3
  gji\-config \- manage global config defaults
4
4
  .SH SYNOPSIS
@@ -1,4 +1,4 @@
1
- .TH GJI\-DOCTOR 1 "July 2026" "gji 0.9.0" "User Commands"
1
+ .TH GJI\-DOCTOR 1 "July 2026" "gji 0.10.0" "User Commands"
2
2
  .SH NAME
3
3
  gji\-doctor \- check gji installation and configuration health
4
4
  .SH SYNOPSIS
package/man/man1/gji-go.1 CHANGED
@@ -1,4 +1,4 @@
1
- .TH GJI\-GO 1 "July 2026" "gji 0.9.0" "User Commands"
1
+ .TH GJI\-GO 1 "July 2026" "gji 0.10.0" "User Commands"
2
2
  .SH NAME
3
3
  gji\-go \- print or select a worktree path
4
4
  .SH SYNOPSIS
@@ -1,4 +1,4 @@
1
- .TH GJI\-HISTORY 1 "July 2026" "gji 0.9.0" "User Commands"
1
+ .TH GJI\-HISTORY 1 "July 2026" "gji 0.10.0" "User Commands"
2
2
  .SH NAME
3
3
  gji\-history \- show navigation history
4
4
  .SH SYNOPSIS
@@ -1,4 +1,4 @@
1
- .TH GJI\-INIT 1 "July 2026" "gji 0.9.0" "User Commands"
1
+ .TH GJI\-INIT 1 "July 2026" "gji 0.10.0" "User Commands"
2
2
  .SH NAME
3
3
  gji\-init \- set up shell integration interactively or print a shell wrapper
4
4
  .SH SYNOPSIS
package/man/man1/gji-ls.1 CHANGED
@@ -1,4 +1,4 @@
1
- .TH GJI\-LS 1 "July 2026" "gji 0.9.0" "User Commands"
1
+ .TH GJI\-LS 1 "July 2026" "gji 0.10.0" "User Commands"
2
2
  .SH NAME
3
3
  gji\-ls \- list active worktrees
4
4
  .SH SYNOPSIS
@@ -1,4 +1,4 @@
1
- .TH GJI\-NEW 1 "July 2026" "gji 0.9.0" "User Commands"
1
+ .TH GJI\-NEW 1 "July 2026" "gji 0.10.0" "User Commands"
2
2
  .SH NAME
3
3
  gji\-new \- create a new branch or detached linked worktree
4
4
  .SH SYNOPSIS
@@ -13,6 +13,9 @@ remove and recreate the worktree if the target path already exists
13
13
  .B \-\-detached
14
14
  create a detached worktree without a branch
15
15
  .TP
16
+ .B \-\-from\-current
17
+ base the new branch on the current worktree instead of the main worktree (cannot be combined with \-\-detached)
18
+ .TP
16
19
  .B \-\-open
17
20
  open the new worktree in an editor after creation
18
21
  .TP
@@ -1,4 +1,4 @@
1
- .TH GJI\-OPEN 1 "July 2026" "gji 0.9.0" "User Commands"
1
+ .TH GJI\-OPEN 1 "July 2026" "gji 0.10.0" "User Commands"
2
2
  .SH NAME
3
3
  gji\-open \- open the worktree in an editor
4
4
  .SH SYNOPSIS
@@ -7,6 +7,9 @@ gji\-open \- open the worktree in an editor
7
7
  open the worktree in an editor
8
8
  .SH OPTIONS
9
9
  .TP
10
+ .B \-\-select
11
+ choose a worktree with the interactive selector
12
+ .TP
10
13
  .B \-\-editor <cli>
11
14
  editor CLI to use (code, cursor, zed, windsurf, subl, …)
12
15
  .TP
package/man/man1/gji-pr.1 CHANGED
@@ -1,4 +1,4 @@
1
- .TH GJI\-PR 1 "July 2026" "gji 0.9.0" "User Commands"
1
+ .TH GJI\-PR 1 "July 2026" "gji 0.10.0" "User Commands"
2
2
  .SH NAME
3
3
  gji\-pr \- fetch a pull request by number, #number, or URL into a linked worktree
4
4
  .SH SYNOPSIS
@@ -1,4 +1,4 @@
1
- .TH GJI\-REMOVE 1 "July 2026" "gji 0.9.0" "User Commands"
1
+ .TH GJI\-REMOVE 1 "July 2026" "gji 0.10.0" "User Commands"
2
2
  .SH NAME
3
3
  gji\-remove \- remove a linked worktree and delete its branch when present
4
4
  .SH SYNOPSIS
@@ -1,4 +1,4 @@
1
- .TH GJI\-ROOT 1 "July 2026" "gji 0.9.0" "User Commands"
1
+ .TH GJI\-ROOT 1 "July 2026" "gji 0.10.0" "User Commands"
2
2
  .SH NAME
3
3
  gji\-root \- print the main repository root path
4
4
  .SH SYNOPSIS
@@ -1,4 +1,4 @@
1
- .TH GJI\-RUN\-HOOK 1 "July 2026" "gji 0.9.0" "User Commands"
1
+ .TH GJI\-RUN\-HOOK 1 "July 2026" "gji 0.10.0" "User Commands"
2
2
  .SH NAME
3
3
  gji\-run\-hook \- run a named hook (after\-create, after\-enter, before\-remove) in the current worktree
4
4
  .SH SYNOPSIS
@@ -1,4 +1,4 @@
1
- .TH GJI\-STATUS 1 "July 2026" "gji 0.9.0" "User Commands"
1
+ .TH GJI\-STATUS 1 "July 2026" "gji 0.10.0" "User Commands"
2
2
  .SH NAME
3
3
  gji\-status \- summarize repository and worktree health
4
4
  .SH SYNOPSIS
@@ -1,4 +1,4 @@
1
- .TH GJI\-SYNC\-FILES 1 "July 2026" "gji 0.9.0" "User Commands"
1
+ .TH GJI\-SYNC\-FILES 1 "July 2026" "gji 0.10.0" "User Commands"
2
2
  .SH NAME
3
3
  gji\-sync\-files \- manage local files copied into new worktrees
4
4
  .SH SYNOPSIS
@@ -1,4 +1,4 @@
1
- .TH GJI\-SYNC 1 "July 2026" "gji 0.9.0" "User Commands"
1
+ .TH GJI\-SYNC 1 "July 2026" "gji 0.10.0" "User Commands"
2
2
  .SH NAME
3
3
  gji\-sync \- fetch and update one or all worktrees
4
4
  .SH SYNOPSIS
@@ -1,4 +1,4 @@
1
- .TH GJI\-WARP 1 "July 2026" "gji 0.9.0" "User Commands"
1
+ .TH GJI\-WARP 1 "July 2026" "gji 0.10.0" "User Commands"
2
2
  .SH NAME
3
3
  gji\-warp \- jump to any worktree across all known repos
4
4
  .SH SYNOPSIS
package/man/man1/gji.1 CHANGED
@@ -1,4 +1,4 @@
1
- .TH GJI 1 "July 2026" "gji 0.9.0" "User Commands"
1
+ .TH GJI 1 "July 2026" "gji 0.10.0" "User Commands"
2
2
  .SH NAME
3
3
  gji \- Context switching without the mess.
4
4
  .SH SYNOPSIS
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solaqua/gji",
3
- "version": "0.9.0",
3
+ "version": "0.10.0",
4
4
  "description": "Git worktree CLI for fast context switching.",
5
5
  "license": "MIT",
6
6
  "author": "sjquant",