Implement a more simplified and extendable project launcher
This commit is contained in:
parent
6a9414a8ca
commit
29ba35a57c
7 changed files with 293 additions and 216 deletions
49
README.md
49
README.md
|
|
@ -46,10 +46,7 @@ home-manager switch --flake github:Logan-Lin/nix-config#yanlin
|
||||||
│ ├── p10k.zsh # Powerlevel10k theme configuration
|
│ ├── p10k.zsh # Powerlevel10k theme configuration
|
||||||
│ └── projects.nix # Project shortcuts configuration
|
│ └── projects.nix # Project shortcuts configuration
|
||||||
└── scripts/ # Utility scripts
|
└── scripts/ # Utility scripts
|
||||||
├── project-launcher.sh # Universal project launcher
|
└── project-launcher.sh # Dynamic project launcher with window configuration
|
||||||
└── templates/ # Tmux session templates
|
|
||||||
├── basic.sh # Basic development template
|
|
||||||
└── research.sh # Research workflow template
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## 🔄 Core Workflow
|
## 🔄 Core Workflow
|
||||||
|
|
@ -156,23 +153,39 @@ proj # List all available projects
|
||||||
nix-config # Launch nix-config project tmux session
|
nix-config # Launch nix-config project tmux session
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Template Types:
|
#### Window-Based Configuration:
|
||||||
- **Basic**: Single directory (nvim + git + shell)
|
Projects are configured with flexible window groups, allowing multiple working directories and customized window types per project.
|
||||||
- **Research**: Code directory + separate paper directory + optional remote server
|
|
||||||
- **Remote Server Window**: Dual horizontal panes for parallel remote work
|
**Window Types:**
|
||||||
- **Automatic Connection**: SSH to configured server with automatic directory navigation
|
- **nvim**: Code editing with Neovim (created by default)
|
||||||
- **Reconnect Alias**: Type `r` in any remote pane to easily reconnect
|
- **ai**: AI assistant with three-pane layout
|
||||||
|
- **git**: Git management with lazygit
|
||||||
|
- **shell**: Plain shell window
|
||||||
|
- **remote**: SSH connection with dual panes
|
||||||
|
|
||||||
**Example Configuration:**
|
**Example Configuration:**
|
||||||
```nix
|
```nix
|
||||||
research-project = {
|
blog = {
|
||||||
template = "research";
|
session = "blog";
|
||||||
name = "Research Project";
|
description = "Personal blog project";
|
||||||
codePath = "~/Projects/research-code";
|
windows = [
|
||||||
paperPath = "~/Projects/research-paper";
|
{
|
||||||
description = "Academic research project";
|
name = "code";
|
||||||
server = "dev-server"; # SSH host from ~/.ssh/config
|
path = "~/Projects/personal-blog";
|
||||||
remoteDir = "~/research"; # Remote directory path
|
ai = true;
|
||||||
|
git = true;
|
||||||
|
remote = {
|
||||||
|
server = "personal-vps"; # SSH host from ~/.ssh/config
|
||||||
|
remoteDir = "~/blog"; # Remote directory path
|
||||||
|
};
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name = "content";
|
||||||
|
path = "~/Projects/personal-blog/content";
|
||||||
|
ai = true;
|
||||||
|
git = true;
|
||||||
|
}
|
||||||
|
];
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,83 +1,178 @@
|
||||||
{
|
{
|
||||||
projects = {
|
projects = {
|
||||||
nix-config = {
|
nix-config = {
|
||||||
template = "basic";
|
session = "nix";
|
||||||
name = "nix";
|
|
||||||
codePath = "/Users/yanlin/.config/nix";
|
|
||||||
description = "Nix configuration";
|
description = "Nix configuration";
|
||||||
|
windows = [
|
||||||
|
{
|
||||||
|
name = "nix";
|
||||||
|
path = "/Users/yanlin/.config/nix";
|
||||||
|
ai = true;
|
||||||
|
git = true;
|
||||||
|
shell = true;
|
||||||
|
}
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
homelab = {
|
homelab = {
|
||||||
template = "basic";
|
session = "homelab";
|
||||||
name = "homelab";
|
|
||||||
codePath = "/Users/yanlin/Documents/Projects/Homelab-deploy";
|
|
||||||
description = "Homelab Deployment";
|
description = "Homelab Deployment";
|
||||||
|
windows = [
|
||||||
|
{
|
||||||
|
name = "homelab";
|
||||||
|
path = "/Users/yanlin/Documents/Projects/Homelab-deploy";
|
||||||
|
ai = true;
|
||||||
|
git = true;
|
||||||
|
shell = true;
|
||||||
|
}
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
note = {
|
note = {
|
||||||
template = "basic";
|
session = "note";
|
||||||
name = "note";
|
|
||||||
codePath = "/Users/yanlin/Obsidian/Personal";
|
|
||||||
description = "Obsidian notes";
|
description = "Obsidian notes";
|
||||||
|
windows = [
|
||||||
|
{
|
||||||
|
name = "note";
|
||||||
|
path = "/Users/yanlin/Obsidian/Personal";
|
||||||
|
ai = true;
|
||||||
|
git = true;
|
||||||
|
shell = false;
|
||||||
|
}
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
acapro = {
|
acapro = {
|
||||||
template = "basic";
|
session = "aca-programs";
|
||||||
name = "aca-programs";
|
|
||||||
codePath = "/Users/yanlin/Documents/Programs";
|
|
||||||
description = "Academic programs";
|
description = "Academic programs";
|
||||||
|
windows = [
|
||||||
|
{
|
||||||
|
name = "pro";
|
||||||
|
path = "/Users/yanlin/Documents/Programs";
|
||||||
|
ai = true;
|
||||||
|
git = true;
|
||||||
|
shell = false;
|
||||||
|
}
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
blog = {
|
blog = {
|
||||||
template = "research";
|
session = "blog";
|
||||||
name = "blog";
|
|
||||||
codePath = "/Users/yanlin/Documents/Projects/personal-blog";
|
|
||||||
paperPath = "/Users/yanlin/Documents/Projects/personal-blog/content";
|
|
||||||
description = "Personal blog project";
|
description = "Personal blog project";
|
||||||
server = "personal-vps";
|
windows = [
|
||||||
remoteDir = "~/blog";
|
{
|
||||||
|
name = "code";
|
||||||
|
path = "/Users/yanlin/Documents/Projects/personal-blog";
|
||||||
|
ai = true;
|
||||||
|
git = true;
|
||||||
|
shell = true;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name = "content";
|
||||||
|
path = "/Users/yanlin/Documents/Projects/personal-blog/content";
|
||||||
|
ai = true;
|
||||||
|
git = false;
|
||||||
|
}
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
homepage = {
|
homepage = {
|
||||||
template = "basic";
|
session = "homepage";
|
||||||
name = "homepage";
|
|
||||||
codePath = "/Users/yanlin/Documents/Projects/Homepage/";
|
|
||||||
description = "Personal Homepage";
|
description = "Personal Homepage";
|
||||||
|
windows = [
|
||||||
|
{
|
||||||
|
name = "homepage";
|
||||||
|
path = "/Users/yanlin/Documents/Projects/Homepage/";
|
||||||
|
ai = true;
|
||||||
|
git = true;
|
||||||
|
shell = true;
|
||||||
|
}
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
mdshortcut = {
|
mdshortcut = {
|
||||||
template = "research";
|
session = "MDShortcut";
|
||||||
name = "MDShortcut";
|
|
||||||
codePath = "/Users/yanlin/Documents/Projects/Material Design Shortcut/MDShortcut-code";
|
|
||||||
paperPath = "/Users/yanlin/Documents/Projects/Material Design Shortcut/MDShortcut-paper";
|
|
||||||
description = "Material design shortcut";
|
description = "Material design shortcut";
|
||||||
server = "aicloud";
|
windows = [
|
||||||
remoteDir = "~/MDS";
|
{
|
||||||
|
name = "code";
|
||||||
|
path = "/Users/yanlin/Documents/Projects/Material Design Shortcut/MDShortcut-code";
|
||||||
|
ai = true;
|
||||||
|
git = true;
|
||||||
|
remote = {
|
||||||
|
server = "aicloud";
|
||||||
|
remoteDir = "~/MDS";
|
||||||
|
};
|
||||||
|
shell = true;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name = "paper";
|
||||||
|
path = "/Users/yanlin/Documents/Projects/Material Design Shortcut/MDShortcut-paper";
|
||||||
|
ai = true;
|
||||||
|
git = true;
|
||||||
|
shell = false;
|
||||||
|
}
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
daki3 = {
|
daki3 = {
|
||||||
template = "research";
|
session = "DAKI3";
|
||||||
name = "DAKI3";
|
|
||||||
codePath = "/Users/yanlin/Documents/Projects/AI systems & infrastructure/Codes";
|
|
||||||
paperPath = "/Users/yanlin/Documents/Projects/AI systems & infrastructure/Slides";
|
|
||||||
description = "DAKI3 course";
|
description = "DAKI3 course";
|
||||||
|
windows = [
|
||||||
|
{
|
||||||
|
name = "code";
|
||||||
|
path = "/Users/yanlin/Documents/Projects/AI systems & infrastructure/Codes";
|
||||||
|
ai = true;
|
||||||
|
git = true;
|
||||||
|
shell = true;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name = "slides";
|
||||||
|
path = "/Users/yanlin/Documents/Projects/AI systems & infrastructure/Slides";
|
||||||
|
ai = true;
|
||||||
|
git = true;
|
||||||
|
shell = false;
|
||||||
|
}
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
matmeet = {
|
matmeet = {
|
||||||
template = "basic";
|
session = "MaterialMeet";
|
||||||
name = "MaterialMeet";
|
|
||||||
codePath = "/Users/yanlin/Documents/Projects/Material Project Group Meeting";
|
|
||||||
description = "Material Meeting Slides";
|
description = "Material Meeting Slides";
|
||||||
|
windows = [
|
||||||
|
{
|
||||||
|
name = "slides";
|
||||||
|
path = "/Users/yanlin/Documents/Projects/Material Project Group Meeting";
|
||||||
|
ai = true;
|
||||||
|
git = true;
|
||||||
|
shell = false;
|
||||||
|
}
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
ddm = {
|
ddm = {
|
||||||
template = "research";
|
session = "DiffDisMatter";
|
||||||
name = "DiffDisMatter";
|
|
||||||
codePath = "/Users/yanlin/Documents/Projects/Inverse Design of Disordered Materials/DiffDisMatter-dev";
|
|
||||||
paperPath = "/Users/yanlin/Documents/Projects/Inverse Design of Disordered Materials/mc-denoising-paper";
|
|
||||||
description = "Inverse material design";
|
description = "Inverse material design";
|
||||||
server = "aicloud";
|
windows = [
|
||||||
remoteDir = "~/DiffDisMatter";
|
{
|
||||||
|
name = "code";
|
||||||
|
path = "/Users/yanlin/Documents/Projects/Inverse Design of Disordered Materials/DiffDisMatter-dev";
|
||||||
|
ai = true;
|
||||||
|
git = true;
|
||||||
|
shell = true;
|
||||||
|
remote = {
|
||||||
|
server = "aicloud";
|
||||||
|
remoteDir = "~/DiffDisMatter";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name = "paper";
|
||||||
|
path = "/Users/yanlin/Documents/Projects/Inverse Design of Disordered Materials/mc-denoising-paper";
|
||||||
|
ai = true;
|
||||||
|
git = true;
|
||||||
|
shell = false;
|
||||||
|
}
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,11 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Universal project launcher - reads project config and launches appropriate template
|
# Universal project launcher - reads project config and launches dynamic windows
|
||||||
# Usage: project-launcher.sh PROJECT_NAME
|
# Usage: project-launcher.sh PROJECT_NAME
|
||||||
|
|
||||||
PROJECT_NAME="$1"
|
PROJECT_NAME="$1"
|
||||||
CONFIG_DIR="$(dirname "$0")/../config"
|
CONFIG_DIR="$(dirname "$0")/../config"
|
||||||
PROJECTS_JSON="$CONFIG_DIR/projects.json"
|
PROJECTS_JSON="$CONFIG_DIR/projects.json"
|
||||||
TEMPLATES_DIR="$(dirname "$0")/templates"
|
|
||||||
|
|
||||||
# Check if tmux session is running
|
# Check if tmux session is running
|
||||||
is_session_running() {
|
is_session_running() {
|
||||||
|
|
@ -25,15 +24,15 @@ if [ -z "$PROJECT_NAME" ]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Parse and display projects with descriptions
|
# Parse and display projects with descriptions
|
||||||
jq -r '.projects | to_entries[] | "\(.key)|\(.value.description)|\(.value.template)|\(.value.name)"' "$PROJECTS_JSON" 2>/dev/null | \
|
jq -r '.projects | to_entries[] | "\(.key)|\(.value.description)|\(.value.session)"' "$PROJECTS_JSON" 2>/dev/null | \
|
||||||
while IFS='|' read -r name desc template session_name; do
|
while IFS='|' read -r name desc session_name; do
|
||||||
# Check if session is running and format accordingly
|
# Check if session is running and format accordingly
|
||||||
if is_session_running "$session_name"; then
|
if is_session_running "$session_name"; then
|
||||||
printf " \033[1;32m%-12s\033[0m \033[2m[%-8s]\033[0m %s\033[1;32m • Running\033[0m\n" \
|
printf " \033[1;32m%-12s\033[0m %s\033[1;32m • Running\033[0m\n" \
|
||||||
"$name" "$template" "$desc"
|
"$name" "$desc"
|
||||||
else
|
else
|
||||||
printf " \033[1;32m%-12s\033[0m \033[2m[%-8s]\033[0m %s\n" \
|
printf " \033[1;32m%-12s\033[0m %s\n" \
|
||||||
"$name" "$template" "$desc"
|
"$name" "$desc"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
@ -62,13 +61,18 @@ if [ "$PROJECT_CONFIG" = "null" ]; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
TEMPLATE=$(echo "$PROJECT_CONFIG" | jq -r '.template')
|
SESSION_NAME=$(echo "$PROJECT_CONFIG" | jq -r '.session')
|
||||||
SESSION_NAME=$(echo "$PROJECT_CONFIG" | jq -r '.name')
|
DESCRIPTION=$(echo "$PROJECT_CONFIG" | jq -r '.description // empty')
|
||||||
CODE_PATH=$(echo "$PROJECT_CONFIG" | jq -r '.codePath')
|
|
||||||
CONTENT_PATH=$(echo "$PROJECT_CONFIG" | jq -r '.contentPath // empty')
|
# Check if session already exists and attach if it does
|
||||||
PAPER_PATH=$(echo "$PROJECT_CONFIG" | jq -r '.paperPath // empty')
|
if is_session_running "$SESSION_NAME"; then
|
||||||
SERVER=$(echo "$PROJECT_CONFIG" | jq -r '.server // empty')
|
printf "\033[1;32mAttaching to existing session: %s\033[0m\n" "$SESSION_NAME"
|
||||||
REMOTE_DIR=$(echo "$PROJECT_CONFIG" | jq -r '.remoteDir // empty')
|
tmux attach-session -t "$SESSION_NAME"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Update papis cache
|
||||||
|
papis cache reset > /dev/null 2>&1
|
||||||
|
|
||||||
# Create directories if they don't exist
|
# Create directories if they don't exist
|
||||||
create_directory() {
|
create_directory() {
|
||||||
|
|
@ -87,55 +91,118 @@ create_directory() {
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Ensure required directories exist
|
# Get windows configuration
|
||||||
create_directory "$CODE_PATH" "code"
|
WINDOWS=$(echo "$PROJECT_CONFIG" | jq -c '.windows[]' 2>/dev/null)
|
||||||
create_directory "$CONTENT_PATH" "content"
|
|
||||||
create_directory "$PAPER_PATH" "paper"
|
|
||||||
|
|
||||||
# Record directories in zoxide for smart navigation
|
if [ -z "$WINDOWS" ]; then
|
||||||
[ -n "$CODE_PATH" ] && [ "$CODE_PATH" != "null" ] && [ -d "$CODE_PATH" ] && zoxide add "$CODE_PATH" 2>/dev/null || true
|
echo "Error: No windows configured for project '$PROJECT_NAME'"
|
||||||
[ -n "$CONTENT_PATH" ] && [ "$CONTENT_PATH" != "null" ] && [ -d "$CONTENT_PATH" ] && zoxide add "$CONTENT_PATH" 2>/dev/null || true
|
exit 1
|
||||||
[ -n "$PAPER_PATH" ] && [ "$PAPER_PATH" != "null" ] && [ -d "$PAPER_PATH" ] && zoxide add "$PAPER_PATH" 2>/dev/null || true
|
|
||||||
|
|
||||||
# Check if session already exists and attach if it does
|
|
||||||
if is_session_running "$SESSION_NAME"; then
|
|
||||||
printf "\033[1;32mAttaching to existing session: %s\033[0m\n" "$SESSION_NAME"
|
|
||||||
tmux attach-session -t "$SESSION_NAME"
|
|
||||||
exit 0
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Update papis cache
|
# Get the first window configuration to create the session
|
||||||
papis cache reset > /dev/null 2>&1
|
FIRST_WINDOW=$(echo "$WINDOWS" | head -n 1)
|
||||||
|
FIRST_WINDOW_NAME=$(echo "$FIRST_WINDOW" | jq -r '.name')
|
||||||
|
FIRST_WINDOW_PATH=$(echo "$FIRST_WINDOW" | jq -r '.path')
|
||||||
|
|
||||||
# Create remote directory if server connection is configured
|
# Create directory for first window
|
||||||
if [ -n "$SERVER" ] && [ -n "$REMOTE_DIR" ]; then
|
create_directory "$FIRST_WINDOW_PATH" "$FIRST_WINDOW_NAME"
|
||||||
printf "\033[2mEnsuring remote directory exists: %s:%s\033[0m\n" "$SERVER" "$REMOTE_DIR"
|
|
||||||
if ssh "$SERVER" "mkdir -p \"$REMOTE_DIR\"" 2>/dev/null; then
|
# Record directory in zoxide for smart navigation
|
||||||
printf "\033[2mRemote directory ready: %s:%s\033[0m\n" "$SERVER" "$REMOTE_DIR"
|
[ -n "$FIRST_WINDOW_PATH" ] && [ "$FIRST_WINDOW_PATH" != "null" ] && [ -d "$FIRST_WINDOW_PATH" ] && zoxide add "$FIRST_WINDOW_PATH" 2>/dev/null || true
|
||||||
else
|
|
||||||
echo "Warning: Could not create or verify remote directory: $SERVER:$REMOTE_DIR"
|
# Create session with first window
|
||||||
echo "Please check SSH connection and permissions."
|
tmux new-session -d -s "$SESSION_NAME" -c "$FIRST_WINDOW_PATH"
|
||||||
|
|
||||||
|
# Initialize window counter
|
||||||
|
WINDOW_INDEX=1
|
||||||
|
|
||||||
|
# Process each window configuration
|
||||||
|
while IFS= read -r window_config; do
|
||||||
|
WINDOW_NAME=$(echo "$window_config" | jq -r '.name')
|
||||||
|
WINDOW_PATH=$(echo "$window_config" | jq -r '.path')
|
||||||
|
|
||||||
|
# Create directory if it doesn't exist (for subsequent windows)
|
||||||
|
if [ "$WINDOW_INDEX" -gt 1 ]; then
|
||||||
|
create_directory "$WINDOW_PATH" "$WINDOW_NAME"
|
||||||
|
# Record directory in zoxide for smart navigation
|
||||||
|
[ -n "$WINDOW_PATH" ] && [ "$WINDOW_PATH" != "null" ] && [ -d "$WINDOW_PATH" ] && zoxide add "$WINDOW_PATH" 2>/dev/null || true
|
||||||
fi
|
fi
|
||||||
fi
|
|
||||||
|
|
||||||
# Launch appropriate template
|
# Check window options
|
||||||
case "$TEMPLATE" in
|
NVIM_ENABLED=$(echo "$window_config" | jq -r '.nvim // true')
|
||||||
"basic")
|
AI_ENABLED=$(echo "$window_config" | jq -r '.ai // false')
|
||||||
exec "$TEMPLATES_DIR/basic.sh" "$SESSION_NAME" "$CODE_PATH"
|
GIT_ENABLED=$(echo "$window_config" | jq -r '.git // false')
|
||||||
;;
|
SHELL_ENABLED=$(echo "$window_config" | jq -r '.shell // false')
|
||||||
"research")
|
REMOTE_CONFIG=$(echo "$window_config" | jq -r '.remote // empty')
|
||||||
if [ -z "$PAPER_PATH" ]; then
|
|
||||||
echo "Error: Research template requires paperPath"
|
# Create nvim window (default behavior unless explicitly disabled)
|
||||||
exit 1
|
if [ "$NVIM_ENABLED" != "false" ]; then
|
||||||
fi
|
if [ "$WINDOW_INDEX" = 1 ]; then
|
||||||
if [ -n "$SERVER" ] && [ -n "$REMOTE_DIR" ]; then
|
# First window - rename the existing session window
|
||||||
exec "$TEMPLATES_DIR/research.sh" "$SESSION_NAME" "$CODE_PATH" "$PAPER_PATH" "$SERVER" "$REMOTE_DIR"
|
tmux rename-window -t "$SESSION_NAME:$WINDOW_INDEX" "${WINDOW_NAME}-nvim"
|
||||||
else
|
else
|
||||||
exec "$TEMPLATES_DIR/research.sh" "$SESSION_NAME" "$CODE_PATH" "$PAPER_PATH"
|
# Subsequent windows - create new window
|
||||||
|
tmux new-window -t "$SESSION_NAME:$WINDOW_INDEX" -n "${WINDOW_NAME}-nvim" -c "$WINDOW_PATH"
|
||||||
fi
|
fi
|
||||||
;;
|
tmux send-keys -t "$SESSION_NAME:$WINDOW_INDEX" "nvim" C-m
|
||||||
*)
|
sleep 0.5 # Brief delay to ensure nvim loads
|
||||||
echo "Error: Unknown template '$TEMPLATE'"
|
tmux send-keys -t "$SESSION_NAME:$WINDOW_INDEX" " e"
|
||||||
exit 1
|
WINDOW_INDEX=$((WINDOW_INDEX + 1))
|
||||||
;;
|
fi
|
||||||
esac
|
|
||||||
|
# Create AI window if enabled
|
||||||
|
if [ "$AI_ENABLED" = "true" ]; then
|
||||||
|
tmux new-window -t "$SESSION_NAME:$WINDOW_INDEX" -n "${WINDOW_NAME}-ai" -c "$WINDOW_PATH"
|
||||||
|
tmux send-keys -t "$SESSION_NAME:$WINDOW_INDEX" "claude -c" C-m
|
||||||
|
tmux split-window -t "$SESSION_NAME:$WINDOW_INDEX" -h -c "$WINDOW_PATH"
|
||||||
|
tmux split-window -t "$SESSION_NAME:$WINDOW_INDEX.2" -v -c "$WINDOW_PATH"
|
||||||
|
tmux select-pane -t "$SESSION_NAME:$WINDOW_INDEX.1"
|
||||||
|
WINDOW_INDEX=$((WINDOW_INDEX + 1))
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create git window if enabled
|
||||||
|
if [ "$GIT_ENABLED" = "true" ]; then
|
||||||
|
tmux new-window -t "$SESSION_NAME:$WINDOW_INDEX" -n "${WINDOW_NAME}-git" -c "$WINDOW_PATH"
|
||||||
|
tmux send-keys -t "$SESSION_NAME:$WINDOW_INDEX" "lazygit" C-m
|
||||||
|
tmux setw -t "$SESSION_NAME:$WINDOW_INDEX" monitor-activity off
|
||||||
|
WINDOW_INDEX=$((WINDOW_INDEX + 1))
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create shell window if enabled
|
||||||
|
if [ "$SHELL_ENABLED" = "true" ]; then
|
||||||
|
tmux new-window -t "$SESSION_NAME:$WINDOW_INDEX" -n "${WINDOW_NAME}-shell" -c "$WINDOW_PATH"
|
||||||
|
WINDOW_INDEX=$((WINDOW_INDEX + 1))
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create remote window if configured
|
||||||
|
if [ -n "$REMOTE_CONFIG" ] && [ "$REMOTE_CONFIG" != "null" ]; then
|
||||||
|
SERVER=$(echo "$REMOTE_CONFIG" | jq -r '.server // empty')
|
||||||
|
REMOTE_DIR=$(echo "$REMOTE_CONFIG" | jq -r '.remoteDir // empty')
|
||||||
|
|
||||||
|
if [ -n "$SERVER" ] && [ -n "$REMOTE_DIR" ]; then
|
||||||
|
# Ensure remote directory exists
|
||||||
|
printf "\033[2mEnsuring remote directory exists: %s:%s\033[0m\n" "$SERVER" "$REMOTE_DIR"
|
||||||
|
if ssh "$SERVER" "mkdir -p \"$REMOTE_DIR\"" 2>/dev/null; then
|
||||||
|
printf "\033[2mRemote directory ready: %s:%s\033[0m\n" "$SERVER" "$REMOTE_DIR"
|
||||||
|
else
|
||||||
|
echo "Warning: Could not create or verify remote directory: $SERVER:$REMOTE_DIR"
|
||||||
|
echo "Please check SSH connection and permissions."
|
||||||
|
fi
|
||||||
|
|
||||||
|
tmux new-window -t "$SESSION_NAME:$WINDOW_INDEX" -n "${WINDOW_NAME}-remote" -c "$WINDOW_PATH"
|
||||||
|
tmux send-keys -t "$SESSION_NAME:$WINDOW_INDEX" "alias r='ssh $SERVER -t \"cd $REMOTE_DIR && exec \\\$SHELL\"'" C-m
|
||||||
|
tmux send-keys -t "$SESSION_NAME:$WINDOW_INDEX" "ssh $SERVER -t 'cd $REMOTE_DIR && exec \$SHELL'" C-m
|
||||||
|
tmux split-window -t "$SESSION_NAME:$WINDOW_INDEX" -h -c "$WINDOW_PATH"
|
||||||
|
tmux send-keys -t "$SESSION_NAME:$WINDOW_INDEX.2" "alias r='ssh $SERVER -t \"cd $REMOTE_DIR && exec \\\$SHELL\"'" C-m
|
||||||
|
tmux send-keys -t "$SESSION_NAME:$WINDOW_INDEX.2" "ssh $SERVER -t 'cd $REMOTE_DIR && exec \$SHELL'" C-m
|
||||||
|
tmux select-pane -t "$SESSION_NAME:$WINDOW_INDEX.1"
|
||||||
|
WINDOW_INDEX=$((WINDOW_INDEX + 1))
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done <<< "$WINDOWS"
|
||||||
|
|
||||||
|
# Select the first window
|
||||||
|
tmux select-window -t "$SESSION_NAME:1"
|
||||||
|
|
||||||
|
# Attach to session
|
||||||
|
tmux attach-session -t "$SESSION_NAME"
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Basic development template - single directory with nvim, ai, git, shell
|
|
||||||
# Usage: basic.sh SESSION_NAME CODE_PATH
|
|
||||||
|
|
||||||
SESSION_NAME="$1"
|
|
||||||
CODE_PATH="$2"
|
|
||||||
|
|
||||||
if [ -z "$SESSION_NAME" ] || [ -z "$CODE_PATH" ]; then
|
|
||||||
echo "Usage: $0 SESSION_NAME CODE_PATH"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
tmux new-session -d -s $SESSION_NAME -c "$CODE_PATH"
|
|
||||||
|
|
||||||
# Record directory in zoxide for smart navigation
|
|
||||||
zoxide add "$CODE_PATH" 2>/dev/null || true
|
|
||||||
tmux rename-window -t $SESSION_NAME:1 "nvim"
|
|
||||||
tmux send-keys -t $SESSION_NAME:1 "nvim" C-m
|
|
||||||
sleep 0.5 # Brief delay to ensure nvim loads
|
|
||||||
tmux send-keys -t $SESSION_NAME:1 " e"
|
|
||||||
tmux new-window -t $SESSION_NAME:2 -n "ai" -c "$CODE_PATH"
|
|
||||||
tmux send-keys -t $SESSION_NAME:2 "claude -c" C-m
|
|
||||||
tmux split-window -t $SESSION_NAME:2 -h -c "$CODE_PATH"
|
|
||||||
tmux split-window -t $SESSION_NAME:2.2 -v -c "$CODE_PATH"
|
|
||||||
tmux select-pane -t $SESSION_NAME:2.1
|
|
||||||
tmux new-window -t $SESSION_NAME:3 -n "git" -c "$CODE_PATH"
|
|
||||||
tmux send-keys -t $SESSION_NAME:3 "lazygit" C-m
|
|
||||||
tmux setw -t $SESSION_NAME:3 monitor-activity off
|
|
||||||
tmux new-window -t $SESSION_NAME:4 -n "shell" -c "$CODE_PATH"
|
|
||||||
|
|
||||||
tmux select-window -t $SESSION_NAME:1
|
|
||||||
|
|
||||||
tmux attach-session -t $SESSION_NAME
|
|
||||||
|
|
@ -1,64 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Research workflow template - code + separate paper directory + optional remote server
|
|
||||||
# Usage: research.sh SESSION_NAME CODE_PATH PAPER_PATH [SERVER] [REMOTE_DIR]
|
|
||||||
|
|
||||||
SESSION_NAME="$1"
|
|
||||||
CODE_PATH="$2"
|
|
||||||
PAPER_PATH="$3"
|
|
||||||
SERVER="$4"
|
|
||||||
REMOTE_DIR="$5"
|
|
||||||
|
|
||||||
if [ -z "$SESSION_NAME" ] || [ -z "$CODE_PATH" ] || [ -z "$PAPER_PATH" ]; then
|
|
||||||
echo "Usage: $0 SESSION_NAME CODE_PATH PAPER_PATH [SERVER] [REMOTE_DIR]"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Create windows for code
|
|
||||||
tmux new-session -d -s $SESSION_NAME -c "$CODE_PATH"
|
|
||||||
|
|
||||||
# Record directories in zoxide for smart navigation
|
|
||||||
zoxide add "$CODE_PATH" 2>/dev/null || true
|
|
||||||
zoxide add "$PAPER_PATH" 2>/dev/null || true
|
|
||||||
tmux rename-window -t $SESSION_NAME:1 "code"
|
|
||||||
tmux send-keys -t $SESSION_NAME:1 "nvim" C-m
|
|
||||||
sleep 0.5 # Brief delay to ensure nvim loads
|
|
||||||
tmux send-keys -t $SESSION_NAME:1 " e"
|
|
||||||
tmux new-window -t $SESSION_NAME:2 -n "code-ai" -c "$CODE_PATH"
|
|
||||||
tmux send-keys -t $SESSION_NAME:2 "claude -c" C-m
|
|
||||||
tmux split-window -t $SESSION_NAME:2 -h -c "$CODE_PATH"
|
|
||||||
tmux split-window -t $SESSION_NAME:2.2 -v -c "$CODE_PATH"
|
|
||||||
tmux select-pane -t $SESSION_NAME:2.1
|
|
||||||
tmux new-window -t $SESSION_NAME:3 -n "code-git" -c "$CODE_PATH"
|
|
||||||
tmux send-keys -t $SESSION_NAME:3 "lazygit" C-m
|
|
||||||
tmux setw -t $SESSION_NAME:3 monitor-activity off
|
|
||||||
|
|
||||||
# Create windows for paper
|
|
||||||
tmux new-window -t $SESSION_NAME:4 -n "paper" -c "$PAPER_PATH"
|
|
||||||
tmux select-window -t $SESSION_NAME:4
|
|
||||||
tmux send-keys -t $SESSION_NAME:4 "nvim" C-m
|
|
||||||
sleep 0.5 # Brief delay to ensure nvim loads
|
|
||||||
tmux send-keys -t $SESSION_NAME:4 " e"
|
|
||||||
tmux new-window -t $SESSION_NAME:5 -n "paper-ai" -c "$PAPER_PATH"
|
|
||||||
tmux send-keys -t $SESSION_NAME:5 "claude -c" C-m
|
|
||||||
tmux split-window -t $SESSION_NAME:5 -h -c "$PAPER_PATH"
|
|
||||||
tmux split-window -t $SESSION_NAME:5.2 -v -c "$PAPER_PATH"
|
|
||||||
tmux select-pane -t $SESSION_NAME:5.1
|
|
||||||
tmux new-window -t $SESSION_NAME:6 -n "paper-git" -c "$PAPER_PATH"
|
|
||||||
tmux send-keys -t $SESSION_NAME:6 "lazygit" C-m
|
|
||||||
tmux setw -t $SESSION_NAME:6 monitor-activity off
|
|
||||||
|
|
||||||
# Create remote server window if server details are provided
|
|
||||||
if [ -n "$SERVER" ] && [ -n "$REMOTE_DIR" ]; then
|
|
||||||
tmux new-window -t $SESSION_NAME:7 -n "remote" -c "$CODE_PATH"
|
|
||||||
tmux send-keys -t $SESSION_NAME:7 "alias r='ssh $SERVER -t \"cd $REMOTE_DIR && exec \\\$SHELL\"'" C-m
|
|
||||||
tmux send-keys -t $SESSION_NAME:7 "ssh $SERVER -t 'cd $REMOTE_DIR && exec \$SHELL'" C-m
|
|
||||||
tmux split-window -t $SESSION_NAME:7 -h -c "$CODE_PATH"
|
|
||||||
tmux send-keys -t $SESSION_NAME:7.2 "alias r='ssh $SERVER -t \"cd $REMOTE_DIR && exec \\\$SHELL\"'" C-m
|
|
||||||
tmux send-keys -t $SESSION_NAME:7.2 "ssh $SERVER -t 'cd $REMOTE_DIR && exec \$SHELL'" C-m
|
|
||||||
tmux select-pane -t $SESSION_NAME:7.1
|
|
||||||
fi
|
|
||||||
|
|
||||||
tmux select-window -t $SESSION_NAME:1
|
|
||||||
|
|
||||||
tmux attach-session -t $SESSION_NAME
|
|
||||||
0
ude -c
Normal file
0
ude -c
Normal file
0
zygit
Normal file
0
zygit
Normal file
Loading…
Add table
Add a link
Reference in a new issue