wtcode 0.3.0__tar.gz → 0.4.0__tar.gz
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.
- {wtcode-0.3.0/wtcode.egg-info → wtcode-0.4.0}/PKG-INFO +2 -1
- {wtcode-0.3.0 → wtcode-0.4.0}/README.md +1 -0
- {wtcode-0.3.0 → wtcode-0.4.0}/pyproject.toml +1 -1
- {wtcode-0.3.0 → wtcode-0.4.0}/wtcode/__init__.py +1 -1
- {wtcode-0.3.0 → wtcode-0.4.0}/wtcode/wtcode.sh +154 -8
- {wtcode-0.3.0 → wtcode-0.4.0/wtcode.egg-info}/PKG-INFO +2 -1
- {wtcode-0.3.0 → wtcode-0.4.0}/LICENSE +0 -0
- {wtcode-0.3.0 → wtcode-0.4.0}/setup.cfg +0 -0
- {wtcode-0.3.0 → wtcode-0.4.0}/wtcode/__main__.py +0 -0
- {wtcode-0.3.0 → wtcode-0.4.0}/wtcode.egg-info/SOURCES.txt +0 -0
- {wtcode-0.3.0 → wtcode-0.4.0}/wtcode.egg-info/dependency_links.txt +0 -0
- {wtcode-0.3.0 → wtcode-0.4.0}/wtcode.egg-info/entry_points.txt +0 -0
- {wtcode-0.3.0 → wtcode-0.4.0}/wtcode.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: wtcode
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: Launch your favorite code tool in a git worktree
|
|
5
5
|
Author-email: Jaeho Shin <netj@sparcs.org>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -61,6 +61,7 @@ wtcode --exec CMD [CMD-ARGS...]
|
|
|
61
61
|
|
|
62
62
|
- **`BRANCH`** -- Git branch or worktree name. If omitted and [fzf](https://github.com/junegunn/fzf) is available, interactively select one. Surround with `:` to create a new branch (use `:::name` or `name:::` to avoid fzf matching the colons).
|
|
63
63
|
- **`CMD`** -- Command to launch in the worktree. Defaults to `$WTCODE_CMD`, or the first available of: `claude`, `aider`, `codex`, `$SHELL`.
|
|
64
|
+
When `CMD` resolves to plain `claude` (no extra args) in a worktree that already existed, wtcode launches `claude /resume` so it opens straight into your last session there. Press `Esc` in the picker to start a new session instead.
|
|
64
65
|
- **`--exec`** -- Skip the branch argument; select interactively via fzf, then launch `CMD`.
|
|
65
66
|
- **`--help`** / **`--version`** -- Show help or version info.
|
|
66
67
|
|
|
@@ -43,6 +43,7 @@ wtcode --exec CMD [CMD-ARGS...]
|
|
|
43
43
|
|
|
44
44
|
- **`BRANCH`** -- Git branch or worktree name. If omitted and [fzf](https://github.com/junegunn/fzf) is available, interactively select one. Surround with `:` to create a new branch (use `:::name` or `name:::` to avoid fzf matching the colons).
|
|
45
45
|
- **`CMD`** -- Command to launch in the worktree. Defaults to `$WTCODE_CMD`, or the first available of: `claude`, `aider`, `codex`, `$SHELL`.
|
|
46
|
+
When `CMD` resolves to plain `claude` (no extra args) in a worktree that already existed, wtcode launches `claude /resume` so it opens straight into your last session there. Press `Esc` in the picker to start a new session instead.
|
|
46
47
|
- **`--exec`** -- Skip the branch argument; select interactively via fzf, then launch `CMD`.
|
|
47
48
|
- **`--help`** / **`--version`** -- Show help or version info.
|
|
48
49
|
|
|
@@ -8,6 +8,10 @@ shopt -s extglob
|
|
|
8
8
|
${WTCODE_DEBUG:+set -x}
|
|
9
9
|
|
|
10
10
|
--msg() { echo "wtcode: $*" >&2; }
|
|
11
|
+
@q() {
|
|
12
|
+
local quoted=$({ set +x; } 2>/dev/null; exec 2>&1; PS4=; set -x; : "$@")
|
|
13
|
+
echo "${quoted:2}" # lstrip the ': ' prefix to get the compact bash-quoted form
|
|
14
|
+
}
|
|
11
15
|
--sanitize-branch-name() {
|
|
12
16
|
printf '%s' "$1" |
|
|
13
17
|
tr '[:upper:]' '[:lower:]' | # lowercase
|
|
@@ -16,7 +20,7 @@ ${WTCODE_DEBUG:+set -x}
|
|
|
16
20
|
sed 's/^-//; s/-$//' # trim leading/trailing hyphens
|
|
17
21
|
}
|
|
18
22
|
|
|
19
|
-
WTCODE_VERSION=0.
|
|
23
|
+
WTCODE_VERSION=0.4.0
|
|
20
24
|
--version() { echo "wtcode $WTCODE_VERSION"; }
|
|
21
25
|
--help() {
|
|
22
26
|
cat <<USAGE
|
|
@@ -43,6 +47,12 @@ Environment variables:
|
|
|
43
47
|
split-window - create split pane with send-keys
|
|
44
48
|
new-window - create new window with send-keys
|
|
45
49
|
exec - exec the tool directly (opt out of send-keys)
|
|
50
|
+
WTCODE_TERMINAL_MODE Outside tmux, control how the tool is launched:
|
|
51
|
+
send-keys - reuse the current tab/window via AppleScript
|
|
52
|
+
(default; macOS only). Terminal.app and Ghostty
|
|
53
|
+
1.3+ use their own scripting support; any other
|
|
54
|
+
terminal falls back to simulated keystrokes
|
|
55
|
+
exec - exec the tool directly (opt out of send-keys)
|
|
46
56
|
WTCODE_DEBUG Enable debug tracing when set
|
|
47
57
|
GIT_WORKTREE_ROOT Override the directory where worktrees are created
|
|
48
58
|
|
|
@@ -69,6 +79,7 @@ WTCODE_CMDS_TO_TRY=(
|
|
|
69
79
|
###############################################################################
|
|
70
80
|
--enter-git-worktree() {
|
|
71
81
|
local branch_name=
|
|
82
|
+
WTCODE_WORKTREE_EXISTED=false
|
|
72
83
|
|
|
73
84
|
# 1. determine which branch/worktree to use
|
|
74
85
|
if [[ $# -gt 0 ]]; then
|
|
@@ -172,6 +183,7 @@ WTCODE_CMDS_TO_TRY=(
|
|
|
172
183
|
if [[ -n $existing_worktree ]]; then
|
|
173
184
|
--msg "branch '$branch_name' is checked out at: $existing_worktree"
|
|
174
185
|
cd "$existing_worktree"
|
|
186
|
+
WTCODE_WORKTREE_EXISTED=true
|
|
175
187
|
return 0
|
|
176
188
|
fi
|
|
177
189
|
fi
|
|
@@ -207,6 +219,7 @@ WTCODE_CMDS_TO_TRY=(
|
|
|
207
219
|
|
|
208
220
|
if [[ -e "$worktree_path"/.git ]]; then
|
|
209
221
|
--msg "using existing worktree: $worktree_path"
|
|
222
|
+
WTCODE_WORKTREE_EXISTED=true
|
|
210
223
|
elif [[ -n ${remote_branch-} ]] && ! git rev-parse --verify "refs/heads/$branch_name" &>/dev/null; then
|
|
211
224
|
# remote branch: create local tracking branch in a new worktree
|
|
212
225
|
--msg "creating worktree for remote branch: $remote_branch"
|
|
@@ -295,6 +308,116 @@ WTCODE_CMDS_TO_TRY=(
|
|
|
295
308
|
--msg "created .claude/.gitignore"
|
|
296
309
|
}
|
|
297
310
|
|
|
311
|
+
###############################################################################
|
|
312
|
+
## --terminal-send-keys -- tmux-like send-keys for GUI terminal apps
|
|
313
|
+
###############################################################################
|
|
314
|
+
# Reuses the current tab/window in the surrounding terminal app, outside
|
|
315
|
+
# tmux. cd_cmd/run_cmd are sent as two separate lines rather than one
|
|
316
|
+
# `cd X && cmd` line, since the shell's PROMPT_COMMAND (what updates the
|
|
317
|
+
# tab/window title via OSC 7/6) only fires between commands, at the next
|
|
318
|
+
# prompt -- a single `&&` line never shows one, so the title would stay
|
|
319
|
+
# stale for as long as cmd runs.
|
|
320
|
+
#
|
|
321
|
+
# macOS-only: dispatches on $TERM_PROGRAM by looking for a matching
|
|
322
|
+
# --terminal-send-keys--macos--$TERM_PROGRAM function -- add support for
|
|
323
|
+
# another terminal app by just defining one, named to match its
|
|
324
|
+
# $TERM_PROGRAM value exactly. `type osascript` fails (and this returns 1)
|
|
325
|
+
# on any other platform, so this whole mechanism is a no-op there and
|
|
326
|
+
# callers just fall back to exec. Also returns 1 if there's no terminal
|
|
327
|
+
# emulator signal (TERM_PROGRAM/TERMINAL_EMULATOR, as in ~/.zprofile) at all.
|
|
328
|
+
--terminal-send-keys() {
|
|
329
|
+
local worktree_path="$PWD"
|
|
330
|
+
local cd_cmd="cd $(@q "$worktree_path")"
|
|
331
|
+
local run_cmd="$(@q "$@")"
|
|
332
|
+
|
|
333
|
+
# TODO: support Linux/general-unix terminals (and SSH sessions) too --
|
|
334
|
+
# e.g. terminals with OSC 7/6 + a way to inject text (wezterm cli,
|
|
335
|
+
# kitty @ send-text, iterm2's escape sequences, etc). For now this whole
|
|
336
|
+
# mechanism is macOS-only and returns 1 (falls back to exec) elsewhere.
|
|
337
|
+
type osascript &>/dev/null || return 1
|
|
338
|
+
|
|
339
|
+
local termprog=${TERM_PROGRAM-${TERMINAL_EMULATOR-}}
|
|
340
|
+
[[ -n $termprog ]] || return 1
|
|
341
|
+
if type -- "--terminal-send-keys--macos--$termprog" &>/dev/null; then
|
|
342
|
+
"--terminal-send-keys--macos--$termprog" "$cd_cmd" "$run_cmd"
|
|
343
|
+
else
|
|
344
|
+
--terminal-send-keys--macos--system-events "$cd_cmd" "$run_cmd"
|
|
345
|
+
fi
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
# `do script ... in front window`: reuses Terminal's front window via a real
|
|
349
|
+
# Apple Event, not a keystroke. `osascript -` reads the script from stdin;
|
|
350
|
+
# without it, osascript treats argv[0] as a script *file* path.
|
|
351
|
+
--terminal-send-keys--macos--Apple_Terminal() {
|
|
352
|
+
local result
|
|
353
|
+
result=$(osascript - "$@" <<'APPLESCRIPT'
|
|
354
|
+
on run argv
|
|
355
|
+
tell application "Terminal"
|
|
356
|
+
try
|
|
357
|
+
repeat with line_cmd in argv
|
|
358
|
+
do script (line_cmd as text) in front window
|
|
359
|
+
end repeat
|
|
360
|
+
set frontmost of front window to true
|
|
361
|
+
return "OK"
|
|
362
|
+
on error
|
|
363
|
+
return "NOTFOUND"
|
|
364
|
+
end try
|
|
365
|
+
end tell
|
|
366
|
+
end run
|
|
367
|
+
APPLESCRIPT
|
|
368
|
+
) || return 1
|
|
369
|
+
[[ $result == OK ]]
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
# Ghostty 1.3+ ships a real AppleScript dictionary: `input text ... to
|
|
373
|
+
# term` targets the terminal focused in the front window's selected tab.
|
|
374
|
+
# Falls back to --macos--system-events since this is still a young feature.
|
|
375
|
+
--terminal-send-keys--macos--ghostty() {
|
|
376
|
+
local result rc
|
|
377
|
+
result=$(osascript - "$@" <<'APPLESCRIPT'
|
|
378
|
+
on run argv
|
|
379
|
+
tell application "Ghostty"
|
|
380
|
+
try
|
|
381
|
+
set term to focused terminal of selected tab of front window
|
|
382
|
+
repeat with line_cmd in argv
|
|
383
|
+
input text ((line_cmd as text) & "\n") to term
|
|
384
|
+
end repeat
|
|
385
|
+
return "OK"
|
|
386
|
+
on error
|
|
387
|
+
return "NOTFOUND"
|
|
388
|
+
end try
|
|
389
|
+
end tell
|
|
390
|
+
end run
|
|
391
|
+
APPLESCRIPT
|
|
392
|
+
); rc=$?
|
|
393
|
+
[[ $rc -eq 0 && $result == OK ]] || --terminal-send-keys--macos--system-events "$@"
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
# Last resort: fake keystrokes via System Events (needs Accessibility
|
|
397
|
+
# permission). No `activate` call -- $TERM_PROGRAM isn't always a real app
|
|
398
|
+
# name, so this relies on the calling terminal still being frontmost.
|
|
399
|
+
--terminal-send-keys--macos--system-events() {
|
|
400
|
+
local result
|
|
401
|
+
result=$(osascript - "$@" <<'APPLESCRIPT'
|
|
402
|
+
on run argv
|
|
403
|
+
tell application "System Events"
|
|
404
|
+
try
|
|
405
|
+
repeat with line_cmd in argv
|
|
406
|
+
keystroke (line_cmd as text)
|
|
407
|
+
key code 36 -- Return
|
|
408
|
+
delay 0.05
|
|
409
|
+
end repeat
|
|
410
|
+
return "OK"
|
|
411
|
+
on error
|
|
412
|
+
return "NOTFOUND"
|
|
413
|
+
end try
|
|
414
|
+
end tell
|
|
415
|
+
end run
|
|
416
|
+
APPLESCRIPT
|
|
417
|
+
) || return 1
|
|
418
|
+
[[ $result == OK ]]
|
|
419
|
+
}
|
|
420
|
+
|
|
298
421
|
###############################################################################
|
|
299
422
|
## --launch-code-tool -- resolve and exec the tool in the worktree
|
|
300
423
|
###############################################################################
|
|
@@ -308,6 +431,14 @@ WTCODE_CMDS_TO_TRY=(
|
|
|
308
431
|
[[ $# -gt 0 ]] || set -- "${SHELL:-bash}"
|
|
309
432
|
fi
|
|
310
433
|
|
|
434
|
+
# default to resuming the last session when relaunching claude in a
|
|
435
|
+
# worktree that already existed; press Esc in the picker to start fresh
|
|
436
|
+
# instead. only kicks in when no CMD-ARGS were given, so explicit flags
|
|
437
|
+
# (e.g. `claude --resume`) are never overridden.
|
|
438
|
+
if [[ $1 == claude && $# -eq 1 && ${WTCODE_WORKTREE_EXISTED:-false} == true ]]; then
|
|
439
|
+
set -- "$1" /resume
|
|
440
|
+
fi
|
|
441
|
+
|
|
311
442
|
[[ $1 == claude ]] && --provision-claude-settings
|
|
312
443
|
|
|
313
444
|
--msg "launching: $*"
|
|
@@ -320,12 +451,7 @@ WTCODE_CMDS_TO_TRY=(
|
|
|
320
451
|
case $mode in
|
|
321
452
|
send-keys|split-window|new-window)
|
|
322
453
|
local worktree_path="$PWD"
|
|
323
|
-
|
|
324
|
-
local quoted_args=()
|
|
325
|
-
for arg in "$@"; do
|
|
326
|
-
quoted_args+=("$(printf '%q' "$arg")")
|
|
327
|
-
done
|
|
328
|
-
local cmd="cd $(printf '%q' "$worktree_path") && ${quoted_args[*]}"
|
|
454
|
+
local cmd="cd $(@q "$worktree_path") && $(@q "$@")"
|
|
329
455
|
|
|
330
456
|
case $mode in
|
|
331
457
|
send-keys)
|
|
@@ -356,7 +482,27 @@ WTCODE_CMDS_TO_TRY=(
|
|
|
356
482
|
esac
|
|
357
483
|
fi
|
|
358
484
|
|
|
359
|
-
# outside tmux
|
|
485
|
+
# outside tmux: reuse the current tab/window if the terminal app supports
|
|
486
|
+
# it (see --terminal-send-keys). set WTCODE_TERMINAL_MODE=exec to opt out
|
|
487
|
+
if [[ -z ${TMUX:-} ]]; then
|
|
488
|
+
local mode=${WTCODE_TERMINAL_MODE:-send-keys}
|
|
489
|
+
case $mode in
|
|
490
|
+
send-keys)
|
|
491
|
+
if --terminal-send-keys "$@"; then
|
|
492
|
+
return 0
|
|
493
|
+
fi
|
|
494
|
+
--msg "could not reuse the current tab/window; falling back to exec"
|
|
495
|
+
;;
|
|
496
|
+
exec)
|
|
497
|
+
# explicitly opt out of send-keys, fall through to exec
|
|
498
|
+
;;
|
|
499
|
+
*)
|
|
500
|
+
--msg "unknown WTCODE_TERMINAL_MODE: $mode (expected: send-keys, exec)"
|
|
501
|
+
;;
|
|
502
|
+
esac
|
|
503
|
+
fi
|
|
504
|
+
|
|
505
|
+
# outside tmux, WTCODE_TMUX_MODE=exec, unsupported terminal, or unknown mode: exec directly
|
|
360
506
|
exec "$@"
|
|
361
507
|
}
|
|
362
508
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: wtcode
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: Launch your favorite code tool in a git worktree
|
|
5
5
|
Author-email: Jaeho Shin <netj@sparcs.org>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -61,6 +61,7 @@ wtcode --exec CMD [CMD-ARGS...]
|
|
|
61
61
|
|
|
62
62
|
- **`BRANCH`** -- Git branch or worktree name. If omitted and [fzf](https://github.com/junegunn/fzf) is available, interactively select one. Surround with `:` to create a new branch (use `:::name` or `name:::` to avoid fzf matching the colons).
|
|
63
63
|
- **`CMD`** -- Command to launch in the worktree. Defaults to `$WTCODE_CMD`, or the first available of: `claude`, `aider`, `codex`, `$SHELL`.
|
|
64
|
+
When `CMD` resolves to plain `claude` (no extra args) in a worktree that already existed, wtcode launches `claude /resume` so it opens straight into your last session there. Press `Esc` in the picker to start a new session instead.
|
|
64
65
|
- **`--exec`** -- Skip the branch argument; select interactively via fzf, then launch `CMD`.
|
|
65
66
|
- **`--help`** / **`--version`** -- Show help or version info.
|
|
66
67
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|