From cd6cbd8d6efce2b6adb0551434be20a11726ad81 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Mon, 28 Jul 2025 02:05:39 +0200 Subject: [PATCH] Add VIBETUNNEL_PREFER_DERIVED_DATA support and version tracking - Add VIBETUNNEL_PREFER_DERIVED_DATA environment variable to vt script - When set, prefers VibeTunnel builds from Xcode's DerivedData - Logs binary location, version, and build timestamp - Falls back to /Applications if no DerivedData build found - Add version and buildDate to StatusResponse interface - Include version info in api-socket-server status responses - Add comprehensive documentation in README.md - Version info already stored in session.json (was pre-existing) This helps developers easily test changes without installing to /Applications --- README.md | 29 ++++++++++++ web/bin/vt | 68 ++++++++++++++++++++------- web/src/server/api-socket-server.ts | 3 ++ web/src/server/pty/socket-protocol.ts | 2 + 4 files changed, 86 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index abf6db87..80ca21d8 100644 --- a/README.md +++ b/README.md @@ -862,6 +862,35 @@ VIBETUNNEL_DEBUG=1 vt your-command Debug logs are written to `~/.vibetunnel/log.txt`. +### Using Development Builds with vt + +When developing VibeTunnel, you can use the `VIBETUNNEL_PREFER_DERIVED_DATA` environment variable to make the `vt` command prefer development builds from Xcode's DerivedData folder: + +```bash +# Enable DerivedData preference +export VIBETUNNEL_PREFER_DERIVED_DATA=1 + +# vt will now search for and use the latest VibeTunnel build from DerivedData +vt your-command +``` + +When this environment variable is set, `vt` will: +1. First search for VibeTunnel builds in `~/Library/Developer/Xcode/DerivedData` +2. Use the most recently modified build found there +3. Fall back to `/Applications/VibeTunnel.app` if no DerivedData build exists +4. Log the exact binary location, version, and build timestamp being used + +This is particularly useful for: +- Testing changes without installing to `/Applications` +- Working with multiple VibeTunnel builds simultaneously +- Quickly switching between development and production versions +- Debugging which version of VibeTunnel is being used + +The version information is also: +- Stored in `session.json` for each session +- Displayed in `vt status` output +- Shown in the initial log output when `VIBETUNNEL_PREFER_DERIVED_DATA` is set + ### Verbosity Control Control the amount of output from VibeTunnel commands: diff --git a/web/bin/vt b/web/bin/vt index f4c72296..7ba4e9a7 100755 --- a/web/bin/vt +++ b/web/bin/vt @@ -20,28 +20,47 @@ if [[ "$OSTYPE" == "darwin"* ]]; then # Get the real path of this script to avoid infinite recursion SCRIPT_REAL_PATH="$(resolve_symlink_macos "${BASH_SOURCE[0]}")" - # Comprehensive Mac app search - try standard locations first, then development locations + # Comprehensive Mac app search - order depends on VIBETUNNEL_PREFER_DERIVED_DATA APP_PATH="" - # First try standard locations with valid binary check - for TRY_PATH in "/Applications/VibeTunnel.app" "$HOME/Applications/VibeTunnel.app"; do - if [ -d "$TRY_PATH" ] && [ -f "$TRY_PATH/Contents/Resources/vibetunnel" ]; then - VT_SCRIPT="$TRY_PATH/Contents/Resources/vt" - if [ -f "$VT_SCRIPT" ] && [ -x "$VT_SCRIPT" ]; then - # Avoid infinite recursion by checking if this is the same script - VT_REAL_PATH="$(resolve_symlink_macos "$VT_SCRIPT")" - if [ "$SCRIPT_REAL_PATH" != "$VT_REAL_PATH" ]; then - exec "$VT_SCRIPT" "$@" + if [ -n "$VIBETUNNEL_PREFER_DERIVED_DATA" ]; then + # When preference is set, try DerivedData first + for CANDIDATE in $(find ~/Library/Developer/Xcode/DerivedData -name "VibeTunnel.app" -type d 2>/dev/null | grep -v "\.dSYM" | grep -v "Index\.noindex" | sort -r); do + if [ -f "$CANDIDATE/Contents/Resources/vibetunnel" ]; then + VT_SCRIPT="$CANDIDATE/Contents/Resources/vt" + if [ -f "$VT_SCRIPT" ] && [ -x "$VT_SCRIPT" ]; then + VT_REAL_PATH="$(resolve_symlink_macos "$VT_SCRIPT")" + if [ "$SCRIPT_REAL_PATH" != "$VT_REAL_PATH" ]; then + exec "$VT_SCRIPT" "$@" + fi fi + APP_PATH="$CANDIDATE" + break fi - APP_PATH="$TRY_PATH" - break - fi - done + done + fi - # If not found in standard locations, search for development builds + # If not found yet, try standard locations if [ -z "$APP_PATH" ]; then - # First try DerivedData (for development) + for TRY_PATH in "/Applications/VibeTunnel.app" "$HOME/Applications/VibeTunnel.app"; do + if [ -d "$TRY_PATH" ] && [ -f "$TRY_PATH/Contents/Resources/vibetunnel" ]; then + VT_SCRIPT="$TRY_PATH/Contents/Resources/vt" + if [ -f "$VT_SCRIPT" ] && [ -x "$VT_SCRIPT" ]; then + # Avoid infinite recursion by checking if this is the same script + VT_REAL_PATH="$(resolve_symlink_macos "$VT_SCRIPT")" + if [ "$SCRIPT_REAL_PATH" != "$VT_REAL_PATH" ]; then + exec "$VT_SCRIPT" "$@" + fi + fi + APP_PATH="$TRY_PATH" + break + fi + done + fi + + # If not found in standard locations and VIBETUNNEL_PREFER_DERIVED_DATA wasn't set, search development builds + if [ -z "$APP_PATH" ] && [ -z "$VIBETUNNEL_PREFER_DERIVED_DATA" ]; then + # Try DerivedData (for development) for CANDIDATE in $(find ~/Library/Developer/Xcode/DerivedData -name "VibeTunnel.app" -type d 2>/dev/null | grep -v "\.dSYM" | grep -v "Index\.noindex"); do if [ -f "$CANDIDATE/Contents/Resources/vibetunnel" ]; then VT_SCRIPT="$CANDIDATE/Contents/Resources/vt" @@ -105,6 +124,23 @@ if [ -z "$VIBETUNNEL_BIN" ]; then fi fi +# Log VibeTunnel binary info when VIBETUNNEL_PREFER_DERIVED_DATA is set +if [ -n "$VIBETUNNEL_PREFER_DERIVED_DATA" ] && [ -n "$VIBETUNNEL_BIN" ]; then + # Get version and build info + VERSION_OUTPUT=$("$VIBETUNNEL_BIN" --version 2>&1) + VERSION_LINE=$(echo "$VERSION_OUTPUT" | grep "^VibeTunnel Server" | head -n 1) + BUILD_LINE=$(echo "$VERSION_OUTPUT" | grep "^Built:" | head -n 1) + + # Always log this info regardless of verbosity level + echo "[VibeTunnel] Using binary: $VIBETUNNEL_BIN" + if [ -n "$VERSION_LINE" ]; then + echo "[VibeTunnel] Version: ${VERSION_LINE#VibeTunnel Server }" + fi + if [ -n "$BUILD_LINE" ]; then + echo "[VibeTunnel] ${BUILD_LINE}" + fi +fi + # Check if we're already inside a VibeTunnel session if [ -n "$VIBETUNNEL_SESSION_ID" ]; then # Special case: handle 'vt title' command inside a session diff --git a/web/src/server/api-socket-server.ts b/web/src/server/api-socket-server.ts index 86254af7..33c7fe6a 100644 --- a/web/src/server/api-socket-server.ts +++ b/web/src/server/api-socket-server.ts @@ -23,6 +23,7 @@ import { createGitError } from './utils/git-error.js'; import { areHooksInstalled, installGitHooks, uninstallGitHooks } from './utils/git-hooks.js'; import { createLogger } from './utils/logger.js'; import { prettifyPath } from './utils/path-prettify.js'; +import { BUILD_DATE, VERSION } from './version.js'; import { createControlEvent } from './websocket/control-protocol.js'; import { controlUnixHandler } from './websocket/control-unix-handler.js'; @@ -255,6 +256,8 @@ export class ApiSocketServer { running: true, port: this.serverPort, url: this.serverUrl, + version: VERSION, + buildDate: BUILD_DATE, followMode, }; diff --git a/web/src/server/pty/socket-protocol.ts b/web/src/server/pty/socket-protocol.ts index c84fee26..85d20e78 100644 --- a/web/src/server/pty/socket-protocol.ts +++ b/web/src/server/pty/socket-protocol.ts @@ -90,6 +90,8 @@ export interface StatusResponse { running: boolean; port?: number; url?: string; + version?: string; + buildDate?: string; followMode?: { enabled: boolean; branch?: string;