wtcode 0.1.4__py3-none-any.whl → 0.3.0__py3-none-any.whl

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/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  """wtcode -- launch your favorite code tool in a git worktree."""
2
2
 
3
- __version__ = "0.1.4"
3
+ __version__ = "0.3.0"
wtcode/wtcode.sh CHANGED
@@ -16,7 +16,7 @@ ${WTCODE_DEBUG:+set -x}
16
16
  sed 's/^-//; s/-$//' # trim leading/trailing hyphens
17
17
  }
18
18
 
19
- WTCODE_VERSION=0.1.4
19
+ WTCODE_VERSION=0.3.0
20
20
  --version() { echo "wtcode $WTCODE_VERSION"; }
21
21
  --help() {
22
22
  cat <<USAGE
@@ -38,6 +38,11 @@ Usage: wtcode [BRANCH] [CMD [CMD-ARGS...]]
38
38
 
39
39
  Environment variables:
40
40
  WTCODE_CMD Default tool to launch (e.g., claude, lazygit, vim)
41
+ WTCODE_TMUX_MODE When in tmux, control how the tool is launched:
42
+ send-keys - send command to current pane (default in tmux)
43
+ split-window - create split pane with send-keys
44
+ new-window - create new window with send-keys
45
+ exec - exec the tool directly (opt out of send-keys)
41
46
  WTCODE_DEBUG Enable debug tracing when set
42
47
  GIT_WORKTREE_ROOT Override the directory where worktrees are created
43
48
 
@@ -223,6 +228,73 @@ WTCODE_CMDS_TO_TRY=(
223
228
  git checkout "$branch_name" --
224
229
  }
225
230
 
231
+ ###############################################################################
232
+ ## --provision-claude-settings -- Claude Code setup, only when launching claude
233
+ ###############################################################################
234
+ # Everything Claude-Code-specific lives here so it runs once, synchronously,
235
+ # before dispatch -- regardless of tmux mode -- and only when the resolved
236
+ # tool is actually `claude`. See the call site in --launch-code-tool.
237
+ --provision-claude-settings() {
238
+ # auto-trust this worktree in Claude Code's global config. Newer Claude
239
+ # Code versions also gate a separate "pre-approves N tool permissions"
240
+ # onboarding screen (shown when .claude/settings.local.json grants
241
+ # auto-approve rules) that hasTrustDialogAccepted alone doesn't suppress --
242
+ # hasCompletedProjectOnboarding is needed too.
243
+ if type jq &>/dev/null && [[ -f ~/.claude.json ]]; then
244
+ (
245
+ export worktree_path="$PWD"
246
+ jq -e '.projects[env.worktree_path]' ~/.claude.json &>/dev/null || {
247
+ jq '.projects[env.worktree_path] = ({} | .hasTrustDialogAccepted = true | .hasCompletedProjectOnboarding = true)' \
248
+ ~/.claude.json >~/.claude.json.wtcode.$$
249
+ mv -f ~/.claude.json.wtcode.$$ ~/.claude.json
250
+ }
251
+ )
252
+ fi
253
+
254
+ # symlink project-local settings from the main worktree, if not already
255
+ # present here -- never clobber a file that's git-tracked, hook-provisioned,
256
+ # or already customized in this worktree (including from a prior run: a
257
+ # dangling/previously-created symlink also counts as "already present").
258
+ local main_root
259
+ main_root=$(
260
+ git_common_dir=$(git rev-parse --git-common-dir)
261
+ cd "$git_common_dir"
262
+ cd ..
263
+ pwd
264
+ )
265
+ [[ -d "$main_root/.claude" ]] || return 0 # nothing to provision from
266
+ [[ "$main_root" == "$PWD" ]] && return 0 # already in the main worktree
267
+
268
+ local name created_names=()
269
+ for name in settings.json settings.local.json; do
270
+ local src="$main_root/.claude/$name" dst="$PWD/.claude/$name"
271
+ [[ -e "$src" ]] || continue # nothing to link
272
+ [[ -e "$dst" || -L "$dst" ]] && continue # don't clobber existing/broken link
273
+ mkdir -p "$PWD/.claude" # safe no-op if .claude/ (with other content) already exists
274
+ ln -s "$src" "$dst"
275
+ --msg "symlinked .claude/$name from main worktree"
276
+ created_names+=("$name")
277
+ done
278
+
279
+ (( ${#created_names[@]} > 0 )) || return 0
280
+
281
+ local gi="$PWD/.claude/.gitignore"
282
+ [[ -e $gi ]] && return 0 # respect a pre-existing, possibly customized file
283
+
284
+ local already_ignored=true
285
+ for name in "${created_names[@]}"; do
286
+ git check-ignore -q ".claude/$name" || already_ignored=false
287
+ done
288
+ $already_ignored && return 0
289
+
290
+ {
291
+ echo '# wtcode: symlinked from the main worktree; never commit these here'
292
+ echo 'settings.json'
293
+ echo 'settings.local.json'
294
+ } >"$gi"
295
+ --msg "created .claude/.gitignore"
296
+ }
297
+
226
298
  ###############################################################################
227
299
  ## --launch-code-tool -- resolve and exec the tool in the worktree
228
300
  ###############################################################################
@@ -236,35 +308,56 @@ WTCODE_CMDS_TO_TRY=(
236
308
  [[ $# -gt 0 ]] || set -- "${SHELL:-bash}"
237
309
  fi
238
310
 
311
+ [[ $1 == claude ]] && --provision-claude-settings
312
+
239
313
  --msg "launching: $*"
240
- if [[ $(type -t "$1") == function ]]; then
241
- "$@"
242
- else
243
- exec "$@"
244
- fi
245
- }
246
314
 
247
- ###############################################################################
248
- ## Command wrappers -- override specific tools with pre-launch setup.
249
- ## Define a function with the tool's name to add custom behavior.
250
- ###############################################################################
315
+ # when inside tmux, default to send-keys for command history access
316
+ # set WTCODE_TMUX_MODE=exec to opt out and exec directly
317
+ if [[ -n ${TMUX:-} ]] && type tmux &>/dev/null; then
318
+ local mode=${WTCODE_TMUX_MODE:-send-keys}
251
319
 
252
- # claude: auto-trust the worktree in Claude Code's config
253
- claude() {
254
- if type jq &>/dev/null && [[ -f ~/.claude.json ]]; then
255
- (
256
- export worktree_path="$PWD"
257
- jq -e '.projects[env.worktree_path]' ~/.claude.json &>/dev/null || {
258
- jq '
259
- .projects[env.worktree_path] = ({}
260
- | .hasTrustDialogAccepted = true
261
- )
262
- ' ~/.claude.json >~/.claude.json.wtcode.$$
263
- mv -f ~/.claude.json.wtcode.$$ ~/.claude.json
264
- }
265
- )
320
+ case $mode in
321
+ send-keys|split-window|new-window)
322
+ local worktree_path="$PWD"
323
+ # quote each argument for shell safety
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[*]}"
329
+
330
+ case $mode in
331
+ send-keys)
332
+ # send to current pane
333
+ tmux send-keys "$cmd" Enter
334
+ return 0
335
+ ;;
336
+ split-window)
337
+ # create split, send there
338
+ tmux split-window -v -c "$worktree_path"
339
+ tmux send-keys "$cmd" Enter
340
+ return 0
341
+ ;;
342
+ new-window)
343
+ # create window, send there
344
+ tmux new-window -c "$worktree_path"
345
+ tmux send-keys "$cmd" Enter
346
+ return 0
347
+ ;;
348
+ esac
349
+ ;;
350
+ exec)
351
+ # explicitly opt out of send-keys, fall through to exec
352
+ ;;
353
+ *)
354
+ --msg "unknown WTCODE_TMUX_MODE: $mode (expected: send-keys, split-window, new-window, exec)"
355
+ ;;
356
+ esac
266
357
  fi
267
- exec claude "$@"
358
+
359
+ # outside tmux, WTCODE_TMUX_MODE=exec, or unknown mode: exec directly
360
+ exec "$@"
268
361
  }
269
362
 
270
363
  ###############################################################################
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wtcode
3
- Version: 0.1.4
3
+ Version: 0.3.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
@@ -88,13 +88,14 @@ WTCODE_CMD=cursor wtcode feature # use cursor as default tool
88
88
 
89
89
  1. **Select/specify a branch** -- pass as argument or pick interactively with fzf
90
90
  2. **Create or switch to the worktree** -- worktrees are organized under `$GIT_WORKTREE_ROOT` (defaults to `../<repo>.worktrees/`)
91
- 3. **Launch a tool** -- runs the specified command (or smart default) inside the worktree
91
+ 3. **Provision Claude Code, if that's what you're launching** -- when the resolved tool is `claude`, the worktree is auto-trusted (skips the "do you trust this folder" dialog) and `.claude/settings.json` / `.claude/settings.local.json` are symlinked in from the main repo if not already present -- never for other tools, never clobbering a file that's already there
92
+ 4. **Launch the tool** -- runs the specified command (or smart default) inside the worktree
92
93
 
93
94
  ## Dependencies
94
95
 
95
96
  - **git** -- required
96
97
  - **[fzf](https://github.com/junegunn/fzf)** -- recommended, for interactive branch selection
97
- - **[jq](https://jqlang.github.io/jq/)** -- optional, for Claude Code auto-trust setup
98
+ - **[jq](https://jqlang.github.io/jq/)** -- optional, for Claude Code auto-trust setup (no dependency needed for the settings symlinking itself)
98
99
 
99
100
  ## License
100
101
 
@@ -0,0 +1,9 @@
1
+ wtcode/__init__.py,sha256=cJWLB8H538LD-fSknoFhd72GG4ZGkEG-8dNn2fvcduA,89
2
+ wtcode/__main__.py,sha256=hOvSYANO-q_rf2yy-AQoEOr18KFRSOF8Ezosf8eeFmM,335
3
+ wtcode/wtcode.sh,sha256=tmXEZlRWulOqEuNbfUdjz68unGl01di8o5tEgnzAk24,15509
4
+ wtcode-0.3.0.dist-info/licenses/LICENSE,sha256=MV9gr1nAVj5R60EM2BQuBhBxCG5V9ulX6-Ep_-LcLqA,1067
5
+ wtcode-0.3.0.dist-info/METADATA,sha256=JrXX6XZ_hAte9V8KSo5jkNRJFwHb5uGlCfypf_ZNhGw,3903
6
+ wtcode-0.3.0.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
7
+ wtcode-0.3.0.dist-info/entry_points.txt,sha256=QkSPHU86FQa-ujQk07fF4sX4DBQgWzDtgusop4AA5bc,48
8
+ wtcode-0.3.0.dist-info/top_level.txt,sha256=oftTSYYjDMqt33wa0c9MC15KuQ3eyRyoTLXy3PdkVfE,7
9
+ wtcode-0.3.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (82.0.1)
2
+ Generator: setuptools (83.0.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,9 +0,0 @@
1
- wtcode/__init__.py,sha256=0ZQh71koVy1Uu4uc2158fJIamOMkJ-ER-gHxB2OBb7s,89
2
- wtcode/__main__.py,sha256=hOvSYANO-q_rf2yy-AQoEOr18KFRSOF8Ezosf8eeFmM,335
3
- wtcode/wtcode.sh,sha256=vhEWnZhhSpOXxaGA4WnOAYotb0opgdySAfZVR4LDyRc,11604
4
- wtcode-0.1.4.dist-info/licenses/LICENSE,sha256=MV9gr1nAVj5R60EM2BQuBhBxCG5V9ulX6-Ep_-LcLqA,1067
5
- wtcode-0.1.4.dist-info/METADATA,sha256=nZZUoSmKYRD3qyc08HFftXAkmjwjiPopBiluwxPZtoc,3477
6
- wtcode-0.1.4.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
7
- wtcode-0.1.4.dist-info/entry_points.txt,sha256=QkSPHU86FQa-ujQk07fF4sX4DBQgWzDtgusop4AA5bc,48
8
- wtcode-0.1.4.dist-info/top_level.txt,sha256=oftTSYYjDMqt33wa0c9MC15KuQ3eyRyoTLXy3PdkVfE,7
9
- wtcode-0.1.4.dist-info/RECORD,,