Skip to content

Instantly share code, notes, and snippets.

@netgfx
Last active December 22, 2025 09:44
Show Gist options
  • Select an option

  • Save netgfx/225fcd8c2bd852588ff9a066f95a5a7a to your computer and use it in GitHub Desktop.

Select an option

Save netgfx/225fcd8c2bd852588ff9a066f95a5a7a to your computer and use it in GitHub Desktop.
context tunnel - bash
#!/bin/bash
# ==========================================
# Tunnel Manager for AI Context
# Usage:
# ./tunnel.sh link <source_path> [target_name]
# ./tunnel.sh unlink [target_name]
# ==========================================
COMMAND=$1
DEFAULT_NAME="TEMPLATE"
# Colors for output
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m' # No Color
function show_usage {
echo -e "Usage:"
echo -e " ${GREEN}./tunnel.sh link <path-to-folder> [alias-name]${NC} (Default alias: $DEFAULT_NAME)"
echo -e " ${GREEN}./tunnel.sh unlink [alias-name]${NC} (Default alias: $DEFAULT_NAME)"
exit 1
}
# Check if command is provided
if [ -z "$COMMAND" ]; then
show_usage
fi
# ==========================================
# LINK COMMAND
# ==========================================
if [ "$COMMAND" == "link" ]; then
SOURCE_PATH=$2
TARGET_NAME=${3:-$DEFAULT_NAME} # Use 3rd arg or default
# 1. Validate Source
if [ -z "$SOURCE_PATH" ]; then
echo -e "${RED}Error: Missing source path.${NC}"
show_usage
fi
if [ ! -d "$SOURCE_PATH" ]; then
echo -e "${RED}Error: Source directory does not exist: $SOURCE_PATH${NC}"
exit 1
fi
# Convert source to absolute path to prevent broken links
# (cd to dir, pwd, then jump back)
ABS_SOURCE_PATH=$(cd "$SOURCE_PATH" && pwd)
# Check for circular links
if [ -L "$ABS_SOURCE_PATH" ]; then
RESOLVED=$(readlink "$ABS_SOURCE_PATH")
CURRENT_DIR=$(pwd)
if [[ "$RESOLVED" == *"$CURRENT_DIR"* ]] || [[ "$RESOLVED" == *"$TARGET_NAME"* ]]; then
echo -e "${RED}Error: Creating this link would form a circular dependency.${NC}"
exit 1
fi
fi
# 2. Check if Target already exists
if [ -e "$TARGET_NAME" ]; then
echo -e "${RED}Error: A file or folder named '$TARGET_NAME' already exists here.${NC}"
exit 1
fi
# 3. Create Symlink
ln -s "$ABS_SOURCE_PATH" "$TARGET_NAME"
echo -e "${GREEN}✔ Linked '$TARGET_NAME' -> '$ABS_SOURCE_PATH'${NC}"
# 4. Handle .gitignore
if [ ! -f .gitignore ]; then
touch .gitignore
echo -e "${YELLOW}Created .gitignore file.${NC}"
fi
# Check if entry exists (grep -q is silent)
if grep -Fxq "$TARGET_NAME" .gitignore; then
echo -e "${GREEN}✔ '$TARGET_NAME' is already in .gitignore${NC}"
else
# Ensure we append to a new line
# Check if file ends with newline, if not add one
if [ -s .gitignore ] && [ "$(tail -c1 .gitignore | wc -l)" -eq 0 ]; then
echo "" >> .gitignore
fi
echo "$TARGET_NAME" >> .gitignore
echo -e "${GREEN}✔ Added '$TARGET_NAME' to .gitignore${NC}"
fi
# ==========================================
# UNLINK COMMAND
# ==========================================
elif [ "$COMMAND" == "unlink" ]; then
TARGET_NAME=${2:-$DEFAULT_NAME} # Use 2nd arg or default
# 1. Validate it exists
if [ ! -e "$TARGET_NAME" ] && [ ! -L "$TARGET_NAME" ]; then
echo -e "${RED}Error: '$TARGET_NAME' not found.${NC}"
exit 1
fi
# 2. Validate it is actually a symlink (Safety Check)
if [ ! -L "$TARGET_NAME" ]; then
echo -e "${RED}CRITICAL ERROR: '$TARGET_NAME' is a real directory, not a link!${NC}"
echo -e "This script will NOT delete real directories to prevent data loss."
exit 1
fi
# 3. Remove the link
# 'unlink' command is safer than 'rm' as it cannot remove directories
unlink "$TARGET_NAME"
echo -e "${GREEN}✔ Unlinked '$TARGET_NAME'${NC}"
# Optional: We usually leave the entry in .gitignore as it does no harm,
# but you could remove it with sed if strict cleanup is needed.
else
show_usage
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment