aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/dot_claude/skills/tuicr/executable_tuicr-wrapper.sh
diff options
context:
space:
mode:
authorLibravatar sommerfeld <sommerfeld@sommerfeld.dev>2026-05-22 10:41:23 +0100
committerLibravatar sommerfeld <sommerfeld@sommerfeld.dev>2026-05-22 10:41:23 +0100
commitc514fe6199cc166dd8fe7f8796d21cd0b22016d6 (patch)
tree6108811f7de6dcea9904f740df0bbdf786e83ae3 /dot_claude/skills/tuicr/executable_tuicr-wrapper.sh
parent668b9846a6eccb16a619f57d305f1bd6bdaeb7bc (diff)
downloaddotfiles-c514fe6199cc166dd8fe7f8796d21cd0b22016d6.tar.gz
dotfiles-c514fe6199cc166dd8fe7f8796d21cd0b22016d6.tar.bz2
dotfiles-c514fe6199cc166dd8fe7f8796d21cd0b22016d6.zip
feat(claude): add tuicr skill (zellij-adapted)
Adapts upstream agavra/tuicr's tmux-based wrapper to zellij: - Detects $ZELLIJ instead of $TMUX - Spawns child via 'zellij action new-pane --floating' (or --direction with TUICR_PANE_MODE=split / TUICR_SPLIT_DIR=down) - Replaces tmux 'wait-for' with a mkfifo / printf done sentinel - Uses 'pgrep -x tuicr' for the cross-pane already-running probe (zellij has no list-panes equivalent) SKILL.md updated for zellij keybinds and a nix install path note.
Diffstat (limited to 'dot_claude/skills/tuicr/executable_tuicr-wrapper.sh')
-rwxr-xr-xdot_claude/skills/tuicr/executable_tuicr-wrapper.sh102
1 files changed, 102 insertions, 0 deletions
diff --git a/dot_claude/skills/tuicr/executable_tuicr-wrapper.sh b/dot_claude/skills/tuicr/executable_tuicr-wrapper.sh
new file mode 100755
index 0000000..d3457fa
--- /dev/null
+++ b/dot_claude/skills/tuicr/executable_tuicr-wrapper.sh
@@ -0,0 +1,102 @@
+#!/usr/bin/env bash
+# tuicr-wrapper: open tuicr in a zellij floating pane (or split) from a
+# non-TTY context (e.g. claude-code, copilot CLI). Blocks on a FIFO until
+# the spawned tuicr process exits, then emits any instructions written by
+# tuicr's --output to stdout, wrapped in markers the agent recognises.
+#
+# Adapted from agavra/tuicr's tmux-based reference wrapper.
+# See: dot_claude/skills/tuicr/SKILL.md
+set -euo pipefail
+
+TARGET_DIR="${1:-$PWD}"
+
+if [ -z "${ZELLIJ:-}" ]; then
+ cat <<'EOF' >&2
+ERROR: not running inside a zellij session.
+
+Restart the agent from inside a zellij session and try again:
+
+ zellij
+ # then, inside zellij:
+ claude # or: copilot
+EOF
+ exit 1
+fi
+
+if ! command -v tuicr >/dev/null 2>&1; then
+ cat <<'EOF' >&2
+ERROR: 'tuicr' is not installed.
+
+Provisioned via nix; rebuild your profile:
+
+ # host (Arch):
+ just nix-switch
+
+ # remote-dev VM:
+ cd ~/.local/share/dotfiles/remote-dev
+ home-manager switch --impure --flake .#vm -b backup
+EOF
+ exit 1
+fi
+
+if ! git -C "$TARGET_DIR" rev-parse --git-dir >/dev/null 2>&1; then
+ echo "ERROR: '$TARGET_DIR' is not a git repository" >&2
+ exit 1
+fi
+
+# Refuse to nest if another tuicr is already running (zellij has no
+# tmux-style 'list-panes | grep'; pgrep is the closest cross-pane probe).
+if pgrep -x tuicr >/dev/null 2>&1; then
+ echo "ERROR: tuicr is already running in this session" >&2
+ exit 1
+fi
+
+# Per-invocation tmpdir holds:
+# done - FIFO; child writes one byte on exit, parent blocks read
+# output - tuicr --output target (instructions to relay back)
+TMPDIR_TUICR="$(mktemp -d -t tuicr.XXXXXX)"
+DONE_FIFO="$TMPDIR_TUICR/done"
+OUTPUT_FILE="$TMPDIR_TUICR/output"
+trap 'rm -rf "$TMPDIR_TUICR"' EXIT
+mkfifo "$DONE_FIFO"
+: >"$OUTPUT_FILE"
+
+PANE_MODE="${TUICR_PANE_MODE:-floating}"
+SPLIT_DIR="${TUICR_SPLIT_DIR:-down}"
+
+# Child command: cd into the repo, run tuicr exporting instructions, then
+# signal the parent regardless of exit status.
+CHILD_CMD="cd $(printf %q "$TARGET_DIR") && \
+ tuicr --output $(printf %q "$OUTPUT_FILE"); \
+ printf done > $(printf %q "$DONE_FIFO")"
+
+case "$PANE_MODE" in
+ floating)
+ zellij action new-pane --floating \
+ --cwd "$TARGET_DIR" \
+ -- bash -lc "$CHILD_CMD" >/dev/null
+ ;;
+ split)
+ zellij action new-pane \
+ --direction "$SPLIT_DIR" \
+ --cwd "$TARGET_DIR" \
+ -- bash -lc "$CHILD_CMD" >/dev/null
+ ;;
+ *)
+ echo "ERROR: invalid TUICR_PANE_MODE='$PANE_MODE' (expected floating|split)" >&2
+ exit 1
+ ;;
+esac
+
+# Block until the child writes its sentinel.
+read -r _ <"$DONE_FIFO"
+
+# Relay instructions back to the agent if tuicr wrote any.
+if [ -s "$OUTPUT_FILE" ]; then
+ echo "=== TUICR INSTRUCTIONS ==="
+ cat "$OUTPUT_FILE"
+ echo
+ echo "=== END TUICR INSTRUCTIONS ==="
+else
+ echo "tuicr exited with no instructions" >&2
+fi