Refactor Constant cockpit runtime and wrappers
This commit is contained in:
@@ -8,7 +8,7 @@ while [[ -L "$script_source" ]]; do
|
||||
[[ "$script_source" != /* ]] && script_source="$script_dir/$script_source"
|
||||
done
|
||||
script_dir="$(cd "$(dirname "$script_source")" && pwd -P)"
|
||||
source "$script_dir/zellij-ai-common.sh"
|
||||
source "$script_dir/constant-common.sh"
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ while [[ -L "$script_source" ]]; do
|
||||
[[ "$script_source" != /* ]] && script_source="$script_dir/$script_source"
|
||||
done
|
||||
script_dir="$(cd "$(dirname "$script_source")" && pwd -P)"
|
||||
source "$script_dir/zellij-ai-common.sh"
|
||||
source "$script_dir/constant-common.sh"
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
script_source="${BASH_SOURCE[0]:-$0}"
|
||||
while [[ -L "$script_source" ]]; do
|
||||
script_dir="$(cd "$(dirname "$script_source")" && pwd -P)"
|
||||
script_source="$(readlink "$script_source")"
|
||||
[[ "$script_source" != /* ]] && script_source="$script_dir/$script_source"
|
||||
done
|
||||
script_dir="$(cd "$(dirname "$script_source")" && pwd -P)"
|
||||
|
||||
export CONSTANT_SCRIPT_NAME="${CONSTANT_SCRIPT_NAME:-$(basename "$0")}"
|
||||
exec "$script_dir/zellij-ai-bootstrap.sh" "$@"
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
script_source="${BASH_SOURCE[0]:-$0}"
|
||||
while [[ -L "$script_source" ]]; do
|
||||
script_dir="$(cd "$(dirname "$script_source")" && pwd -P)"
|
||||
script_source="$(readlink "$script_source")"
|
||||
[[ "$script_source" != /* ]] && script_source="$script_dir/$script_source"
|
||||
done
|
||||
script_dir="$(cd "$(dirname "$script_source")" && pwd -P)"
|
||||
|
||||
export CONSTANT_SCRIPT_NAME="${CONSTANT_SCRIPT_NAME:-$(basename "$0")}"
|
||||
exec "$script_dir/zellij-ai-claude-pane.sh" "$@"
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
script_source="${BASH_SOURCE[0]:-$0}"
|
||||
while [[ -L "$script_source" ]]; do
|
||||
script_dir="$(cd "$(dirname "$script_source")" && pwd -P)"
|
||||
script_source="$(readlink "$script_source")"
|
||||
[[ "$script_source" != /* ]] && script_source="$script_dir/$script_source"
|
||||
done
|
||||
script_dir="$(cd "$(dirname "$script_source")" && pwd -P)"
|
||||
|
||||
export CONSTANT_SCRIPT_NAME="${CONSTANT_SCRIPT_NAME:-$(basename "$0")}"
|
||||
exec "$script_dir/zellij-ai-codex-pane.sh" "$@"
|
||||
Executable
+12
@@ -0,0 +1,12 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
script_source="${BASH_SOURCE[0]:-$0}"
|
||||
while [[ -L "$script_source" ]]; do
|
||||
script_dir="$(cd "$(dirname "$script_source")" && pwd -P)"
|
||||
script_source="$(readlink "$script_source")"
|
||||
[[ "$script_source" != /* ]] && script_source="$script_dir/$script_source"
|
||||
done
|
||||
script_dir="$(cd "$(dirname "$script_source")" && pwd -P)"
|
||||
|
||||
source "$script_dir/zellij-ai-common.sh"
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
script_source="${BASH_SOURCE[0]:-$0}"
|
||||
while [[ -L "$script_source" ]]; do
|
||||
script_dir="$(cd "$(dirname "$script_source")" && pwd -P)"
|
||||
script_source="$(readlink "$script_source")"
|
||||
[[ "$script_source" != /* ]] && script_source="$script_dir/$script_source"
|
||||
done
|
||||
script_dir="$(cd "$(dirname "$script_source")" && pwd -P)"
|
||||
|
||||
export CONSTANT_SCRIPT_NAME="${CONSTANT_SCRIPT_NAME:-$(basename "$0")}"
|
||||
exec "$script_dir/zellij-ai-copilot-pane.sh" "$@"
|
||||
@@ -10,4 +10,4 @@ done
|
||||
script_dir="$(cd "$(dirname "$script_source")" && pwd -P)"
|
||||
|
||||
export CONSTANT_SCRIPT_NAME="$(basename "$0")"
|
||||
exec "$script_dir/zellij-ai-fleet-deploy.sh" "$@"
|
||||
exec "$script_dir/constant-fleet-deploy.sh" "$@"
|
||||
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
script_source="${BASH_SOURCE[0]:-$0}"
|
||||
while [[ -L "$script_source" ]]; do
|
||||
script_dir="$(cd "$(dirname "$script_source")" && pwd -P)"
|
||||
script_source="$(readlink "$script_source")"
|
||||
[[ "$script_source" != /* ]] && script_source="$script_dir/$script_source"
|
||||
done
|
||||
script_dir="$(cd "$(dirname "$script_source")" && pwd -P)"
|
||||
|
||||
export CONSTANT_SCRIPT_NAME="${CONSTANT_SCRIPT_NAME:-$(basename "$0")}"
|
||||
exec "$script_dir/zellij-ai-fleet-bootstrap.sh" "$@"
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
script_source="${BASH_SOURCE[0]:-$0}"
|
||||
while [[ -L "$script_source" ]]; do
|
||||
script_dir="$(cd "$(dirname "$script_source")" && pwd -P)"
|
||||
script_source="$(readlink "$script_source")"
|
||||
[[ "$script_source" != /* ]] && script_source="$script_dir/$script_source"
|
||||
done
|
||||
script_dir="$(cd "$(dirname "$script_source")" && pwd -P)"
|
||||
|
||||
export CONSTANT_SCRIPT_NAME="${CONSTANT_SCRIPT_NAME:-$(basename "$0")}"
|
||||
exec "$script_dir/zellij-ai-fleet-deploy.sh" "$@"
|
||||
@@ -10,4 +10,4 @@ done
|
||||
script_dir="$(cd "$(dirname "$script_source")" && pwd -P)"
|
||||
|
||||
export CONSTANT_SCRIPT_NAME="$(basename "$0")"
|
||||
exec "$script_dir/zellij-ai-fleet.sh" "$@"
|
||||
exec "$script_dir/constant-tmux-fleet.sh" "$@"
|
||||
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
script_source="${BASH_SOURCE[0]:-$0}"
|
||||
while [[ -L "$script_source" ]]; do
|
||||
script_dir="$(cd "$(dirname "$script_source")" && pwd -P)"
|
||||
script_source="$(readlink "$script_source")"
|
||||
[[ "$script_source" != /* ]] && script_source="$script_dir/$script_source"
|
||||
done
|
||||
script_dir="$(cd "$(dirname "$script_source")" && pwd -P)"
|
||||
|
||||
export CONSTANT_SCRIPT_NAME="${CONSTANT_SCRIPT_NAME:-$(basename "$0")}"
|
||||
exec "$script_dir/zellij-ai-machine-install.sh" "$@"
|
||||
@@ -10,4 +10,4 @@ done
|
||||
script_dir="$(cd "$(dirname "$script_source")" && pwd -P)"
|
||||
|
||||
export CONSTANT_SCRIPT_NAME="$(basename "$0")"
|
||||
exec "$script_dir/zellij-ai-triple.sh" "$@"
|
||||
exec "$script_dir/constant-tmux-machine.sh" "$@"
|
||||
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
script_source="${BASH_SOURCE[0]:-$0}"
|
||||
while [[ -L "$script_source" ]]; do
|
||||
script_dir="$(cd "$(dirname "$script_source")" && pwd -P)"
|
||||
script_source="$(readlink "$script_source")"
|
||||
[[ "$script_source" != /* ]] && script_source="$script_dir/$script_source"
|
||||
done
|
||||
script_dir="$(cd "$(dirname "$script_source")" && pwd -P)"
|
||||
|
||||
export CONSTANT_SCRIPT_NAME="${CONSTANT_SCRIPT_NAME:-$(basename "$0")}"
|
||||
exec "$script_dir/zellij-ai-remote-tab.sh" "$@"
|
||||
Executable
+254
@@ -0,0 +1,254 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
script_source="${BASH_SOURCE[0]:-$0}"
|
||||
while [[ -L "$script_source" ]]; do
|
||||
script_dir="$(cd "$(dirname "$script_source")" && pwd -P)"
|
||||
script_source="$(readlink "$script_source")"
|
||||
[[ "$script_source" != /* ]] && script_source="$script_dir/$script_source"
|
||||
done
|
||||
script_dir="$(cd "$(dirname "$script_source")" && pwd -P)"
|
||||
source "$script_dir/constant-common.sh"
|
||||
|
||||
usage() {
|
||||
local script_name="${CONSTANT_SCRIPT_NAME:-$(basename "$0")}"
|
||||
cat <<EOF
|
||||
Usage: ${script_name} --workspace DIR [options]
|
||||
|
||||
Open the Constant tmux fleet cockpit with one central window and one window per machine.
|
||||
|
||||
Options:
|
||||
--workspace DIR Shared workspace path
|
||||
--session NAME Machine tmux session name
|
||||
default: $(zellij_ai_default_session)
|
||||
--local-session NAME Fleet tmux session name on this machine
|
||||
default: $(zellij_ai_default_local_session)
|
||||
--repo-dir DIR Constant repo path on each machine
|
||||
default: $(zellij_ai_default_repo_dir)
|
||||
--machine SPEC Machine definition or label to include
|
||||
--claude-config-dir D Claude config directory for the Claude pane
|
||||
--recreate Recreate the local fleet session before launch
|
||||
--remote-recreate Recreate each machine tmux session before attach
|
||||
--attach-only Attach to an existing local fleet session
|
||||
--ensure-only Create/update the fleet session, then exit
|
||||
-h, --help Show this help
|
||||
EOF
|
||||
}
|
||||
|
||||
require_arg() {
|
||||
local flag="$1"
|
||||
local value="${2:-}"
|
||||
if [[ -z "$value" ]]; then
|
||||
echo "Missing value for ${flag}" >&2
|
||||
exit 2
|
||||
fi
|
||||
}
|
||||
|
||||
build_constant_window_command() {
|
||||
local inner
|
||||
printf -v inner 'cd %q && export PATH=%q; exec %q tui --workspace %q --local-session %q --session %q' \
|
||||
"$workspace" \
|
||||
"$(zellij_ai_agent_path)" \
|
||||
"$repo_dir/scripts/Constant" \
|
||||
"$workspace" \
|
||||
"$local_session" \
|
||||
"$remote_session"
|
||||
printf 'bash -lc %q' "$inner"
|
||||
}
|
||||
|
||||
build_remote_window_command() {
|
||||
local label="$1"
|
||||
local target="$2"
|
||||
local inner remote_script cmd cmd_joined
|
||||
|
||||
remote_script="$repo_dir/scripts/constant-tmux-remote-window.sh"
|
||||
cmd=(
|
||||
"$remote_script"
|
||||
--label "$label"
|
||||
--target "$target"
|
||||
--workspace "$workspace_spec"
|
||||
--repo-dir "$repo_dir_spec"
|
||||
--session "$remote_session"
|
||||
)
|
||||
if [[ -n "$claude_config_dir" ]]; then
|
||||
cmd+=(--claude-config-dir "$claude_config_dir")
|
||||
fi
|
||||
if $remote_recreate; then
|
||||
cmd+=(--recreate)
|
||||
fi
|
||||
|
||||
printf -v cmd_joined '%q ' "${cmd[@]}"
|
||||
printf -v inner 'cd %q && export PATH=%q; exec %s' \
|
||||
"$repo_dir" \
|
||||
"$(zellij_ai_agent_path)" \
|
||||
"$cmd_joined"
|
||||
printf 'bash -lc %q' "$inner"
|
||||
}
|
||||
|
||||
link_local_window() {
|
||||
local label="$1"
|
||||
local launcher="$repo_dir/scripts/constant-machine.sh"
|
||||
local args=(
|
||||
--workspace "$workspace"
|
||||
--session "$remote_session"
|
||||
--repo-dir "$repo_dir"
|
||||
--ensure-only
|
||||
)
|
||||
|
||||
if [[ ! -x "$launcher" ]]; then
|
||||
launcher="$repo_dir/scripts/constant-tmux-machine.sh"
|
||||
fi
|
||||
if [[ -n "$claude_config_dir" ]]; then
|
||||
args+=(--claude-config-dir "$claude_config_dir")
|
||||
fi
|
||||
if $remote_recreate; then
|
||||
args+=(--recreate)
|
||||
fi
|
||||
|
||||
ZELLIJ_AI_MACHINE_NAME="$label" "$launcher" "${args[@]}"
|
||||
if ! constant_tmux_window_exists "$local_session" "$label"; then
|
||||
tmux link-window -d -s "${remote_session}:${label}" -t "${local_session}:"
|
||||
fi
|
||||
}
|
||||
|
||||
constant_tmux_require
|
||||
zellij_ai_require_command ssh
|
||||
|
||||
workspace=""
|
||||
workspace_spec=""
|
||||
remote_session="$(zellij_ai_default_session)"
|
||||
local_session="$(zellij_ai_default_local_session)"
|
||||
repo_dir="$(zellij_ai_expand_home_path "$(zellij_ai_default_repo_dir)")"
|
||||
repo_dir_spec="$(zellij_ai_default_repo_dir)"
|
||||
claude_config_dir=""
|
||||
recreate=false
|
||||
remote_recreate=false
|
||||
attach_only=false
|
||||
ensure_only=false
|
||||
machines=()
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--workspace)
|
||||
require_arg "$1" "${2:-}"
|
||||
workspace_spec="$2"
|
||||
workspace="$(zellij_ai_expand_home_path "$2")"
|
||||
shift 2
|
||||
;;
|
||||
--session)
|
||||
require_arg "$1" "${2:-}"
|
||||
remote_session="$2"
|
||||
shift 2
|
||||
;;
|
||||
--local-session)
|
||||
require_arg "$1" "${2:-}"
|
||||
local_session="$2"
|
||||
shift 2
|
||||
;;
|
||||
--repo-dir)
|
||||
require_arg "$1" "${2:-}"
|
||||
repo_dir_spec="$2"
|
||||
repo_dir="$(zellij_ai_expand_home_path "$2")"
|
||||
shift 2
|
||||
;;
|
||||
--machine)
|
||||
require_arg "$1" "${2:-}"
|
||||
machines+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--claude-config-dir)
|
||||
require_arg "$1" "${2:-}"
|
||||
claude_config_dir="$(zellij_ai_expand_home_path "$2")"
|
||||
shift 2
|
||||
;;
|
||||
--recreate)
|
||||
recreate=true
|
||||
shift
|
||||
;;
|
||||
--remote-recreate)
|
||||
remote_recreate=true
|
||||
shift
|
||||
;;
|
||||
--attach-only)
|
||||
attach_only=true
|
||||
shift
|
||||
;;
|
||||
--ensure-only)
|
||||
ensure_only=true
|
||||
shift
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option: $1" >&2
|
||||
usage >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if $attach_only; then
|
||||
if [[ -n "${TMUX:-}" ]]; then
|
||||
exec tmux switch-client -t "$local_session"
|
||||
fi
|
||||
exec tmux attach-session -t "$local_session"
|
||||
fi
|
||||
|
||||
if [[ -z "$workspace" ]]; then
|
||||
usage >&2
|
||||
exit 2
|
||||
fi
|
||||
if [[ ! -d "$workspace" ]]; then
|
||||
echo "Workspace not found: $workspace" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ${#machines[@]} -eq 0 ]]; then
|
||||
mapfile -t machines < <(zellij_ai_default_machine_specs)
|
||||
fi
|
||||
|
||||
if $recreate && constant_tmux_session_exists "$local_session"; then
|
||||
tmux kill-session -t "$local_session" >/dev/null 2>&1 || true
|
||||
fi
|
||||
|
||||
if constant_tmux_session_exists "$local_session"; then
|
||||
if [[ -n "${TMUX:-}" ]]; then
|
||||
exec tmux switch-client -t "$local_session"
|
||||
fi
|
||||
exec tmux attach-session -t "$local_session"
|
||||
fi
|
||||
|
||||
mkdir -p "$(zellij_ai_fleet_state_dir "$local_session")"
|
||||
tmux new-session -d -s "$local_session" -n Constant "$(build_constant_window_command)"
|
||||
tmux set-option -t "$local_session" -g set-clipboard on >/dev/null 2>&1 || true
|
||||
tmux set-option -t "$local_session" -g remain-on-exit on >/dev/null 2>&1 || true
|
||||
tmux set-option -t "$local_session" -g mouse on >/dev/null 2>&1 || true
|
||||
|
||||
for machine_spec in "${machines[@]}"; do
|
||||
parsed_spec="$(zellij_ai_parse_machine_spec "$machine_spec")"
|
||||
IFS=$'\t' read -r label target <<<"$parsed_spec"
|
||||
|
||||
if [[ "$label" == "Constant" ]]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
if zellij_ai_is_local_target "$target"; then
|
||||
link_local_window "$label"
|
||||
else
|
||||
tmux new-window -d -t "${local_session}:" -n "$label" "$(build_remote_window_command "$label" "$target")"
|
||||
fi
|
||||
done
|
||||
|
||||
tmux select-window -t "${local_session}:Constant" >/dev/null 2>&1 || true
|
||||
|
||||
if $ensure_only; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ -n "${TMUX:-}" ]]; then
|
||||
exec tmux switch-client -t "$local_session"
|
||||
else
|
||||
exec tmux attach-session -t "$local_session"
|
||||
fi
|
||||
Executable
+318
@@ -0,0 +1,318 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
script_source="${BASH_SOURCE[0]:-$0}"
|
||||
while [[ -L "$script_source" ]]; do
|
||||
script_dir="$(cd "$(dirname "$script_source")" && pwd -P)"
|
||||
script_source="$(readlink "$script_source")"
|
||||
[[ "$script_source" != /* ]] && script_source="$script_dir/$script_source"
|
||||
done
|
||||
script_dir="$(cd "$(dirname "$script_source")" && pwd -P)"
|
||||
source "$script_dir/constant-common.sh"
|
||||
|
||||
usage() {
|
||||
local script_name="${CONSTANT_SCRIPT_NAME:-$(basename "$0")}"
|
||||
cat <<EOF
|
||||
Usage: ${script_name} [options]
|
||||
|
||||
Create or control the host-local tmux cockpit for one machine.
|
||||
|
||||
Options:
|
||||
--workspace DIR Workspace for all 4 panes
|
||||
default: current directory
|
||||
--session NAME Machine tmux session name
|
||||
default: $(zellij_ai_default_session)
|
||||
--repo-dir DIR Repo containing Constant scripts
|
||||
default: $(zellij_ai_default_repo_dir)
|
||||
--codex-home DIR Codex profile directory
|
||||
default: $(zellij_ai_default_codex_home)
|
||||
--claude-config-dir D Claude config directory passed to the Claude pane
|
||||
--recreate Kill and recreate the machine session
|
||||
--ensure-only Ensure the session exists, then exit
|
||||
--focus-pane ROLE Focus one pane: claude|codex|copilot|vibe
|
||||
--capture-pane ROLE Print pane capture for the selected role
|
||||
--send-pane ROLE Send --command text to the selected pane
|
||||
--restart-pane ROLE Respawn the selected pane with its launcher command
|
||||
--command TEXT Text to send with --send-pane
|
||||
--lines N Lines to print with --capture-pane
|
||||
default: 120
|
||||
-h, --help Show this help
|
||||
EOF
|
||||
}
|
||||
|
||||
require_arg() {
|
||||
local flag="$1"
|
||||
local value="${2:-}"
|
||||
if [[ -z "$value" ]]; then
|
||||
echo "Missing value for ${flag}" >&2
|
||||
exit 2
|
||||
fi
|
||||
}
|
||||
|
||||
tmux_target_window() {
|
||||
printf '%s:%s\n' "$session" "$machine_name"
|
||||
}
|
||||
|
||||
role_pane_id() {
|
||||
local role="$1"
|
||||
tmux list-panes -t "$(tmux_target_window)" -F '#{pane_id} #{@constant_role} #{pane_title}' 2>/dev/null | awk -F '\t' -v role="$role" '$2 == role || $3 == role {print $1; exit}'
|
||||
}
|
||||
|
||||
ensure_workspace() {
|
||||
if [[ ! -d "$workspace" ]]; then
|
||||
echo "Workspace not found: $workspace" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
pane_command() {
|
||||
constant_tmux_role_command "$1" "$script_dir" "$workspace" "$repo_dir" "$session" "$bus_dir" "$machine_name" "$codex_home" "$claude_config_dir"
|
||||
}
|
||||
|
||||
set_pane_meta() {
|
||||
local pane_id="$1"
|
||||
local role="$2"
|
||||
tmux select-pane -t "$pane_id" -T "$role" >/dev/null 2>&1 || true
|
||||
tmux set-option -p -t "$pane_id" @constant_role "$role" >/dev/null 2>&1 || true
|
||||
}
|
||||
|
||||
create_session() {
|
||||
local target_window claude_cmd codex_cmd copilot_cmd vibe_cmd
|
||||
local claude_pane codex_pane copilot_pane vibe_pane
|
||||
|
||||
target_window="$(tmux_target_window)"
|
||||
claude_cmd="$(pane_command claude)"
|
||||
codex_cmd="$(pane_command codex)"
|
||||
copilot_cmd="$(pane_command copilot)"
|
||||
vibe_cmd="$(pane_command vibe)"
|
||||
|
||||
tmux new-session -d -s "$session" -n "$machine_name" "$claude_cmd"
|
||||
tmux set-option -t "$session" -g set-clipboard on >/dev/null 2>&1 || true
|
||||
tmux set-option -t "$session" -g remain-on-exit on >/dev/null 2>&1 || true
|
||||
tmux set-option -t "$session" -g mouse on >/dev/null 2>&1 || true
|
||||
tmux set-option -t "$session" -g status-position top >/dev/null 2>&1 || true
|
||||
tmux set-window-option -t "$target_window" -g pane-base-index 0 >/dev/null 2>&1 || true
|
||||
|
||||
claude_pane="$(tmux list-panes -t "$target_window" -F '#{pane_id}' | head -n 1)"
|
||||
codex_pane="$(tmux split-window -h -P -F '#{pane_id}' -t "$claude_pane" "$codex_cmd")"
|
||||
copilot_pane="$(tmux split-window -v -P -F '#{pane_id}' -t "$codex_pane" "$copilot_cmd")"
|
||||
vibe_pane="$(tmux split-window -v -P -F '#{pane_id}' -t "$copilot_pane" "$vibe_cmd")"
|
||||
|
||||
tmux select-layout -t "$target_window" main-vertical >/dev/null
|
||||
tmux resize-pane -t "$claude_pane" -x 120 >/dev/null 2>&1 || true
|
||||
set_pane_meta "$claude_pane" claude
|
||||
set_pane_meta "$codex_pane" codex
|
||||
set_pane_meta "$copilot_pane" copilot
|
||||
set_pane_meta "$vibe_pane" vibe
|
||||
tmux select-pane -t "$claude_pane" >/dev/null
|
||||
}
|
||||
|
||||
ensure_session() {
|
||||
mkdir -p "$state_dir" "$bus_dir/messages"
|
||||
|
||||
if $recreate && constant_tmux_session_exists "$session"; then
|
||||
tmux kill-session -t "$session" >/dev/null 2>&1 || true
|
||||
fi
|
||||
|
||||
if ! constant_tmux_session_exists "$session"; then
|
||||
create_session
|
||||
return 0
|
||||
fi
|
||||
|
||||
if ! constant_tmux_window_exists "$session" "$machine_name"; then
|
||||
recreate=true
|
||||
tmux kill-session -t "$session" >/dev/null 2>&1 || true
|
||||
create_session
|
||||
fi
|
||||
}
|
||||
|
||||
focus_role() {
|
||||
local role="$1"
|
||||
local pane_id
|
||||
|
||||
ensure_session
|
||||
pane_id="$(role_pane_id "$role")"
|
||||
if [[ -z "$pane_id" ]]; then
|
||||
echo "No pane found for role: $role" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
tmux select-window -t "$(tmux_target_window)" >/dev/null
|
||||
tmux select-pane -t "$pane_id" >/dev/null
|
||||
}
|
||||
|
||||
restart_role() {
|
||||
local role="$1"
|
||||
local pane_id command_string
|
||||
|
||||
ensure_session
|
||||
pane_id="$(role_pane_id "$role")"
|
||||
if [[ -z "$pane_id" ]]; then
|
||||
echo "No pane found for role: $role" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
command_string="$(pane_command "$role")"
|
||||
tmux respawn-pane -k -t "$pane_id" "$command_string"
|
||||
set_pane_meta "$pane_id" "$role"
|
||||
tmux select-layout -t "$(tmux_target_window)" main-vertical >/dev/null
|
||||
}
|
||||
|
||||
capture_role() {
|
||||
local role="$1"
|
||||
local pane_id
|
||||
|
||||
ensure_session
|
||||
pane_id="$(role_pane_id "$role")"
|
||||
if [[ -z "$pane_id" ]]; then
|
||||
echo "No pane found for role: $role" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
tmux capture-pane -p -S "-${lines}" -t "$pane_id"
|
||||
}
|
||||
|
||||
send_role() {
|
||||
local role="$1"
|
||||
local pane_id
|
||||
|
||||
require_arg --command "$send_command"
|
||||
ensure_session
|
||||
pane_id="$(role_pane_id "$role")"
|
||||
if [[ -z "$pane_id" ]]; then
|
||||
echo "No pane found for role: $role" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
tmux send-keys -t "$pane_id" -l "$send_command"
|
||||
tmux send-keys -t "$pane_id" Enter
|
||||
}
|
||||
|
||||
session="$(zellij_ai_default_session)"
|
||||
workspace="$PWD"
|
||||
repo_dir="$(zellij_ai_expand_home_path "$(zellij_ai_default_repo_dir)")"
|
||||
codex_home="$(zellij_ai_expand_home_path "$(zellij_ai_default_codex_home)")"
|
||||
claude_config_dir=""
|
||||
machine_name="${ZELLIJ_AI_MACHINE_NAME:-$(zellij_ai_local_machine_label)}"
|
||||
recreate=false
|
||||
ensure_only=false
|
||||
focus_pane=""
|
||||
capture_pane=""
|
||||
restart_pane=""
|
||||
send_pane=""
|
||||
send_command=""
|
||||
lines=120
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--workspace)
|
||||
require_arg "$1" "${2:-}"
|
||||
workspace="$(zellij_ai_expand_home_path "$2")"
|
||||
shift 2
|
||||
;;
|
||||
--session)
|
||||
require_arg "$1" "${2:-}"
|
||||
session="$2"
|
||||
shift 2
|
||||
;;
|
||||
--repo-dir)
|
||||
require_arg "$1" "${2:-}"
|
||||
repo_dir="$(zellij_ai_expand_home_path "$2")"
|
||||
shift 2
|
||||
;;
|
||||
--codex-home)
|
||||
require_arg "$1" "${2:-}"
|
||||
codex_home="$(zellij_ai_expand_home_path "$2")"
|
||||
shift 2
|
||||
;;
|
||||
--claude-config-dir)
|
||||
require_arg "$1" "${2:-}"
|
||||
claude_config_dir="$(zellij_ai_expand_home_path "$2")"
|
||||
shift 2
|
||||
;;
|
||||
--recreate)
|
||||
recreate=true
|
||||
shift
|
||||
;;
|
||||
--ensure-only)
|
||||
ensure_only=true
|
||||
shift
|
||||
;;
|
||||
--focus-pane)
|
||||
require_arg "$1" "${2:-}"
|
||||
focus_pane="$2"
|
||||
shift 2
|
||||
;;
|
||||
--capture-pane)
|
||||
require_arg "$1" "${2:-}"
|
||||
capture_pane="$2"
|
||||
shift 2
|
||||
;;
|
||||
--send-pane)
|
||||
require_arg "$1" "${2:-}"
|
||||
send_pane="$2"
|
||||
shift 2
|
||||
;;
|
||||
--restart-pane)
|
||||
require_arg "$1" "${2:-}"
|
||||
restart_pane="$2"
|
||||
shift 2
|
||||
;;
|
||||
--command)
|
||||
require_arg "$1" "${2:-}"
|
||||
send_command="$2"
|
||||
shift 2
|
||||
;;
|
||||
--lines)
|
||||
require_arg "$1" "${2:-}"
|
||||
lines="$2"
|
||||
shift 2
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option: $1" >&2
|
||||
usage >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
constant_tmux_require
|
||||
ensure_workspace
|
||||
state_dir="$(zellij_ai_session_state_dir "$session")"
|
||||
bus_dir="$state_dir/bus"
|
||||
|
||||
if [[ -n "$focus_pane" ]]; then
|
||||
focus_role "$focus_pane"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ -n "$capture_pane" ]]; then
|
||||
capture_role "$capture_pane"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ -n "$send_pane" ]]; then
|
||||
send_role "$send_pane"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ -n "$restart_pane" ]]; then
|
||||
restart_role "$restart_pane"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
ensure_session
|
||||
|
||||
if $ensure_only; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ -n "${TMUX:-}" ]]; then
|
||||
exec tmux switch-client -t "$session"
|
||||
else
|
||||
exec tmux attach-session -t "$session"
|
||||
fi
|
||||
Executable
+136
@@ -0,0 +1,136 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
script_source="${BASH_SOURCE[0]:-$0}"
|
||||
while [[ -L "$script_source" ]]; do
|
||||
script_dir="$(cd "$(dirname "$script_source")" && pwd -P)"
|
||||
script_source="$(readlink "$script_source")"
|
||||
[[ "$script_source" != /* ]] && script_source="$script_dir/$script_source"
|
||||
done
|
||||
script_dir="$(cd "$(dirname "$script_source")" && pwd -P)"
|
||||
source "$script_dir/constant-common.sh"
|
||||
|
||||
usage() {
|
||||
local script_name="${CONSTANT_SCRIPT_NAME:-$(basename "$0")}"
|
||||
cat <<EOF
|
||||
Usage: ${script_name} --label LABEL --target TARGET --workspace DIR [options]
|
||||
|
||||
Attach a fleet window to the host-local tmux machine session on a local or remote target.
|
||||
|
||||
Options:
|
||||
--label LABEL Machine label used for the window title
|
||||
--target TARGET SSH target or local
|
||||
--workspace DIR Workspace path passed to the machine launcher
|
||||
--repo-dir DIR Repo path on the target
|
||||
default: $(zellij_ai_default_repo_dir)
|
||||
--session NAME Machine tmux session name
|
||||
default: $(zellij_ai_default_session)
|
||||
--claude-config-dir DIR Claude config directory on the target
|
||||
--recreate Recreate the target machine session before attach
|
||||
-h, --help Show this help
|
||||
EOF
|
||||
}
|
||||
|
||||
require_arg() {
|
||||
local flag="$1"
|
||||
local value="${2:-}"
|
||||
if [[ -z "$value" ]]; then
|
||||
echo "Missing value for ${flag}" >&2
|
||||
exit 2
|
||||
fi
|
||||
}
|
||||
|
||||
label=""
|
||||
target=""
|
||||
workspace=""
|
||||
repo_dir="$(zellij_ai_default_repo_dir)"
|
||||
session="$(zellij_ai_default_session)"
|
||||
claude_config_dir=""
|
||||
recreate=false
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--label)
|
||||
require_arg "$1" "${2:-}"
|
||||
label="$2"
|
||||
shift 2
|
||||
;;
|
||||
--target)
|
||||
require_arg "$1" "${2:-}"
|
||||
target="$2"
|
||||
shift 2
|
||||
;;
|
||||
--workspace)
|
||||
require_arg "$1" "${2:-}"
|
||||
workspace="$2"
|
||||
shift 2
|
||||
;;
|
||||
--repo-dir)
|
||||
require_arg "$1" "${2:-}"
|
||||
repo_dir="$2"
|
||||
shift 2
|
||||
;;
|
||||
--session)
|
||||
require_arg "$1" "${2:-}"
|
||||
session="$2"
|
||||
shift 2
|
||||
;;
|
||||
--claude-config-dir)
|
||||
require_arg "$1" "${2:-}"
|
||||
claude_config_dir="$2"
|
||||
shift 2
|
||||
;;
|
||||
--recreate)
|
||||
recreate=true
|
||||
shift
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option: $1" >&2
|
||||
usage >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
[[ -n "$label" ]] || { usage >&2; exit 2; }
|
||||
[[ -n "$target" ]] || { usage >&2; exit 2; }
|
||||
[[ -n "$workspace" ]] || { usage >&2; exit 2; }
|
||||
|
||||
if zellij_ai_is_local_target "$target"; then
|
||||
local_repo_dir="$(zellij_ai_expand_home_path "$repo_dir")"
|
||||
local_workspace="$(zellij_ai_expand_home_path "$workspace")"
|
||||
launcher="$local_repo_dir/scripts/constant-machine.sh"
|
||||
args=(
|
||||
--workspace "$local_workspace"
|
||||
--session "$session"
|
||||
--repo-dir "$local_repo_dir"
|
||||
)
|
||||
[[ -x "$launcher" ]] || launcher="$local_repo_dir/scripts/constant-tmux-machine.sh"
|
||||
if [[ -n "$claude_config_dir" ]]; then
|
||||
args+=(--claude-config-dir "$claude_config_dir")
|
||||
fi
|
||||
if $recreate; then
|
||||
args+=(--recreate)
|
||||
fi
|
||||
exec env ZELLIJ_AI_MACHINE_NAME="$label" "$launcher" "${args[@]}"
|
||||
fi
|
||||
|
||||
printf -v remote_inner 'repo_dir=%q; workspace=%q; session_name=%q; repo_dir="${repo_dir#\\}"; workspace="${workspace#\\}"; case "$repo_dir" in \$HOME|\$HOME/*) repo_dir="${HOME}${repo_dir#\$HOME}" ;; "~") repo_dir="$HOME" ;; ~/*) repo_dir="$HOME/${repo_dir#~/}" ;; esac; case "$workspace" in \$HOME|\$HOME/*) workspace="${HOME}${workspace#\$HOME}" ;; "~") workspace="$HOME" ;; ~/*) workspace="$HOME/${workspace#~/}" ;; esac; launcher="$repo_dir/scripts/constant-machine.sh"; if [[ ! -x "$launcher" ]]; then launcher="$repo_dir/scripts/constant-tmux-machine.sh"; fi; args=(--workspace "$workspace" --session "$session_name" --repo-dir "$repo_dir");' \
|
||||
"$repo_dir" \
|
||||
"$workspace" \
|
||||
"$session"
|
||||
|
||||
if [[ -n "$claude_config_dir" ]]; then
|
||||
printf -v remote_inner '%s args+=(--claude-config-dir %q);' "$remote_inner" "$claude_config_dir"
|
||||
fi
|
||||
|
||||
if $recreate; then
|
||||
printf -v remote_inner '%s args+=(--recreate);' "$remote_inner"
|
||||
fi
|
||||
|
||||
printf -v remote_inner '%s exec env ZELLIJ_AI_MACHINE_NAME=%q ZELLIJ_AI_FORCE_OSC52=true "$launcher" "${args[@]}"' "$remote_inner" "$label"
|
||||
exec ssh -tt "$target" bash -lc "$remote_inner"
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
script_source="${BASH_SOURCE[0]:-$0}"
|
||||
while [[ -L "$script_source" ]]; do
|
||||
script_dir="$(cd "$(dirname "$script_source")" && pwd -P)"
|
||||
script_source="$(readlink "$script_source")"
|
||||
[[ "$script_source" != /* ]] && script_source="$script_dir/$script_source"
|
||||
done
|
||||
script_dir="$(cd "$(dirname "$script_source")" && pwd -P)"
|
||||
|
||||
export CONSTANT_SCRIPT_NAME="${CONSTANT_SCRIPT_NAME:-$(basename "$0")}"
|
||||
exec "$script_dir/zellij-ai-vibe-pane.sh" "$@"
|
||||
@@ -18,9 +18,9 @@ fi
|
||||
if [[ -n "$bootstrap_file" && ! -f "$bootstrap_file" ]]; then
|
||||
: >"$bootstrap_file"
|
||||
|
||||
printf -v codex_cmd '%q' "$script_dir/zellij-ai-codex-pane.sh"
|
||||
printf -v copilot_cmd '%q' "$script_dir/zellij-ai-copilot-pane.sh"
|
||||
printf -v vibe_cmd '%q' "$script_dir/zellij-ai-vibe-pane.sh"
|
||||
printf -v codex_cmd '%q' "$script_dir/constant-codex-pane.sh"
|
||||
printf -v copilot_cmd '%q' "$script_dir/constant-copilot-pane.sh"
|
||||
printf -v vibe_cmd '%q' "$script_dir/constant-vibe-pane.sh"
|
||||
|
||||
zellij action new-pane -d right -n "${ZELLIJ_AI_CODEX_LABEL:-codex}" --cwd "$workspace"
|
||||
zellij action move-focus right
|
||||
@@ -40,4 +40,4 @@ if [[ -n "$bootstrap_file" && ! -f "$bootstrap_file" ]]; then
|
||||
zellij action move-focus left
|
||||
fi
|
||||
|
||||
exec "$script_dir/zellij-ai-claude-pane.sh"
|
||||
exec "$script_dir/constant-claude-pane.sh"
|
||||
|
||||
@@ -8,7 +8,7 @@ while [[ -L "$script_source" ]]; do
|
||||
[[ "$script_source" != /* ]] && script_source="$script_dir/$script_source"
|
||||
done
|
||||
script_dir="$(cd "$(dirname "$script_source")" && pwd -P)"
|
||||
source "$script_dir/zellij-ai-common.sh"
|
||||
source "$script_dir/constant-common.sh"
|
||||
|
||||
workspace="${ZELLIJ_AI_WORKSPACE:-$PWD}"
|
||||
machine_name="${ZELLIJ_AI_MACHINE_NAME:-unknown}"
|
||||
|
||||
@@ -8,11 +8,12 @@ while [[ -L "$script_source" ]]; do
|
||||
[[ "$script_source" != /* ]] && script_source="$script_dir/$script_source"
|
||||
done
|
||||
script_dir="$(cd "$(dirname "$script_source")" && pwd -P)"
|
||||
source "$script_dir/zellij-ai-common.sh"
|
||||
source "$script_dir/constant-common.sh"
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage: zellij-ai-codex-pane.sh [slot]
|
||||
local script_name="${CONSTANT_SCRIPT_NAME:-$(basename "$0")}"
|
||||
cat <<EOF
|
||||
Usage: ${script_name} [slot]
|
||||
|
||||
slot:
|
||||
1 Deprecated alias for the single host-local Codex pane
|
||||
|
||||
@@ -96,7 +96,7 @@ zellij_ai_default_codex_image() {
|
||||
}
|
||||
|
||||
zellij_ai_runtime_root() {
|
||||
printf '%s\n' "${ZELLIJ_AI_RUNTIME_ROOT:-$HOME/.cache/constant/zellij}"
|
||||
printf '%s\n' "${ZELLIJ_AI_RUNTIME_ROOT:-$HOME/.cache/constant/cockpit}"
|
||||
}
|
||||
|
||||
zellij_ai_session_state_dir() {
|
||||
@@ -133,7 +133,7 @@ zellij_ai_strip_ansi() {
|
||||
}
|
||||
|
||||
zellij_ai_session_exists() {
|
||||
zellij list-sessions 2>/dev/null | zellij_ai_strip_ansi | awk '{print $1}' | grep -Fxq "$1"
|
||||
tmux has-session -t "$1" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
zellij_ai_kdl_escape() {
|
||||
@@ -271,3 +271,86 @@ zellij_ai_agent_path() {
|
||||
|
||||
printf '%s\n' "$path_value"
|
||||
}
|
||||
|
||||
constant_tmux_require() {
|
||||
zellij_ai_require_command tmux
|
||||
}
|
||||
|
||||
constant_tmux_session_exists() {
|
||||
tmux has-session -t "$1" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
constant_tmux_window_exists() {
|
||||
local session_name="$1"
|
||||
local window_name="$2"
|
||||
tmux list-windows -t "$session_name" -F '#{window_name}' 2>/dev/null | grep -Fxq "$window_name"
|
||||
}
|
||||
|
||||
constant_tmux_base_command() {
|
||||
local role="$1"
|
||||
local launcher="$2"
|
||||
local workspace="$3"
|
||||
local repo_dir="$4"
|
||||
local session_name="$5"
|
||||
local bus_dir="$6"
|
||||
local machine_name="$7"
|
||||
local codex_home="$8"
|
||||
local claude_config_dir="$9"
|
||||
local inner
|
||||
|
||||
printf -v inner \
|
||||
'cd %q && export ZELLIJ_AI_WORKSPACE=%q ZELLIJ_AI_REPO_DIR=%q ZELLIJ_AI_SESSION=%q ZELLIJ_AI_BUS_DIR=%q ZELLIJ_AI_MACHINE_NAME=%q ZELLIJ_AI_CODEX_HOME=%q ZELLIJ_AI_CODEX_LABEL=%q ZELLIJ_AI_COPILOT_LABEL=%q ZELLIJ_AI_VIBE_LABEL=%q ZELLIJ_AI_ROLE=%q PATH=%q;' \
|
||||
"$workspace" \
|
||||
"$workspace" \
|
||||
"$repo_dir" \
|
||||
"$session_name" \
|
||||
"$bus_dir" \
|
||||
"$machine_name" \
|
||||
"$codex_home" \
|
||||
"codex" \
|
||||
"copilot" \
|
||||
"vibe" \
|
||||
"$role" \
|
||||
"$(zellij_ai_agent_path)"
|
||||
|
||||
if [[ -n "$claude_config_dir" ]]; then
|
||||
printf -v inner '%s export ZELLIJ_AI_CLAUDE_CONFIG_DIR=%q;' "$inner" "$claude_config_dir"
|
||||
fi
|
||||
|
||||
printf -v inner '%s exec %q' "$inner" "$launcher"
|
||||
printf 'bash -lc %q' "$inner"
|
||||
}
|
||||
|
||||
constant_tmux_role_command() {
|
||||
local role="$1"
|
||||
local script_dir="$2"
|
||||
local workspace="$3"
|
||||
local repo_dir="$4"
|
||||
local session_name="$5"
|
||||
local bus_dir="$6"
|
||||
local machine_name="$7"
|
||||
local codex_home="$8"
|
||||
local claude_config_dir="$9"
|
||||
local launcher=""
|
||||
|
||||
case "$role" in
|
||||
claude)
|
||||
launcher="$script_dir/constant-claude-pane.sh"
|
||||
;;
|
||||
codex)
|
||||
launcher="$script_dir/constant-codex-pane.sh"
|
||||
;;
|
||||
copilot)
|
||||
launcher="$script_dir/constant-copilot-pane.sh"
|
||||
;;
|
||||
vibe)
|
||||
launcher="$script_dir/constant-vibe-pane.sh"
|
||||
;;
|
||||
*)
|
||||
echo "Unknown Constant pane role: $role" >&2
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
|
||||
constant_tmux_base_command "$role" "$launcher" "$workspace" "$repo_dir" "$session_name" "$bus_dir" "$machine_name" "$codex_home" "$claude_config_dir"
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ while [[ -L "$script_source" ]]; do
|
||||
[[ "$script_source" != /* ]] && script_source="$script_dir/$script_source"
|
||||
done
|
||||
script_dir="$(cd "$(dirname "$script_source")" && pwd -P)"
|
||||
source "$script_dir/zellij-ai-common.sh"
|
||||
source "$script_dir/constant-common.sh"
|
||||
|
||||
workspace="${ZELLIJ_AI_WORKSPACE:-$PWD}"
|
||||
machine_name="${ZELLIJ_AI_MACHINE_NAME:-unknown}"
|
||||
|
||||
@@ -8,7 +8,7 @@ while [[ -L "$script_source" ]]; do
|
||||
[[ "$script_source" != /* ]] && script_source="$script_dir/$script_source"
|
||||
done
|
||||
script_dir="$(cd "$(dirname "$script_source")" && pwd -P)"
|
||||
source "$script_dir/zellij-ai-common.sh"
|
||||
source "$script_dir/constant-common.sh"
|
||||
|
||||
usage() {
|
||||
local script_name="${CONSTANT_SCRIPT_NAME:-$(basename "$0")}"
|
||||
@@ -450,7 +450,7 @@ for raw in finalized.read_text(encoding="utf-8").splitlines():
|
||||
"target": "local",
|
||||
"auto_clis": ["codex", "vibe", "claude"],
|
||||
"manual_clis": ["copilot"],
|
||||
"backends": ["omc", "cli-local", "zellij"],
|
||||
"backends": ["omc", "cli-local", "cockpit"],
|
||||
}
|
||||
)
|
||||
else:
|
||||
@@ -460,7 +460,7 @@ for raw in finalized.read_text(encoding="utf-8").splitlines():
|
||||
"target": f"{user}@{seed}",
|
||||
"auto_clis": ["codex", "vibe", "claude"],
|
||||
"manual_clis": ["copilot"],
|
||||
"backends": ["cli-ssh", "zellij"],
|
||||
"backends": ["cli-ssh", "cockpit"],
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ while [[ -L "$script_source" ]]; do
|
||||
done
|
||||
script_dir="$(cd "$(dirname "$script_source")" && pwd -P)"
|
||||
repo_source="$(cd "$script_dir/.." && pwd -P)"
|
||||
source "$script_dir/zellij-ai-common.sh"
|
||||
source "$script_dir/constant-common.sh"
|
||||
|
||||
usage() {
|
||||
local script_name="${CONSTANT_SCRIPT_NAME:-$(basename "$0")}"
|
||||
@@ -176,20 +176,20 @@ for machine_spec in "${machines[@]}"; do
|
||||
fi
|
||||
|
||||
if zellij_ai_is_local_target "$target"; then
|
||||
ZELLIJ_AI_MACHINE_NAME="$label" "$script_dir/zellij-ai-machine-install.sh" "${install_args[@]}" || overall_status=1
|
||||
ZELLIJ_AI_MACHINE_NAME="$label" "$script_dir/constant-machine-install.sh" "${install_args[@]}" || overall_status=1
|
||||
continue
|
||||
fi
|
||||
|
||||
if [[ "$mode" == "install" ]]; then
|
||||
remote_script="${target_repo_dir}/scripts/zellij-ai-machine-install.sh"
|
||||
remote_script="${target_repo_dir}/scripts/constant-machine-install.sh"
|
||||
ssh -tt "$target" env ZELLIJ_AI_MACHINE_NAME="$label" "$remote_script" "${install_args[@]}" || overall_status=1
|
||||
continue
|
||||
fi
|
||||
|
||||
if $yes; then
|
||||
ssh "$target" env ZELLIJ_AI_MACHINE_NAME="$label" bash -s -- "${install_args[@]}" <"$script_dir/zellij-ai-machine-install.sh" || overall_status=1
|
||||
ssh "$target" env ZELLIJ_AI_MACHINE_NAME="$label" bash -s -- "${install_args[@]}" <"$script_dir/constant-machine-install.sh" || overall_status=1
|
||||
else
|
||||
ssh "$target" env ZELLIJ_AI_MACHINE_NAME="$label" bash -s -- "${install_args[@]}" <"$script_dir/zellij-ai-machine-install.sh" || overall_status=1
|
||||
ssh "$target" env ZELLIJ_AI_MACHINE_NAME="$label" bash -s -- "${install_args[@]}" <"$script_dir/constant-machine-install.sh" || overall_status=1
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
+2
-239
@@ -8,243 +8,6 @@ while [[ -L "$script_source" ]]; do
|
||||
[[ "$script_source" != /* ]] && script_source="$script_dir/$script_source"
|
||||
done
|
||||
script_dir="$(cd "$(dirname "$script_source")" && pwd -P)"
|
||||
repo_dir="$(cd "$script_dir/.." && pwd -P)"
|
||||
source "$script_dir/zellij-ai-common.sh"
|
||||
|
||||
warn_deprecated() {
|
||||
printf 'Warning: %s\n' "$*" >&2
|
||||
}
|
||||
|
||||
usage() {
|
||||
local script_name="${CONSTANT_SCRIPT_NAME:-$(basename "$0")}"
|
||||
cat <<EOF
|
||||
Usage: ${script_name} [options]
|
||||
|
||||
Open a local Zellij cockpit with one tab per machine.
|
||||
Each tab attaches to the machine's own local Constant machine session.
|
||||
|
||||
Options:
|
||||
--machine SPEC Machine definition. Repeat once per machine.
|
||||
format: [TAB_NAME=]TARGET
|
||||
default fleet: command-center, builder-a, builder-b, edge-a, lab-a
|
||||
--session NAME Remote/local machine session name
|
||||
default: $(zellij_ai_default_session)
|
||||
--local-session NAME Cockpit session name on this machine
|
||||
default: $(zellij_ai_default_local_session)
|
||||
--repo-dir DIR Repository path on each machine
|
||||
default: $(zellij_ai_default_repo_dir)
|
||||
--workspace DIR Workspace path passed to each machine session
|
||||
required for the fixed 5-machine fleet
|
||||
--codex-image IMAGE Deprecated, ignored
|
||||
--claude-config DIR Optional Claude config override passed to each machine
|
||||
--remote-recreate Recreate each machine session before attaching
|
||||
--recreate Recreate the local cockpit session before launching
|
||||
-h, --help Show this help
|
||||
EOF
|
||||
}
|
||||
|
||||
machines=()
|
||||
remote_session="$(zellij_ai_default_session)"
|
||||
local_session="$(zellij_ai_default_local_session)"
|
||||
remote_repo_dir="$(zellij_ai_default_repo_dir)"
|
||||
workspace=""
|
||||
codex_image=""
|
||||
claude_config_dir=""
|
||||
recreate=false
|
||||
remote_recreate=false
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--machine)
|
||||
machines+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--session)
|
||||
remote_session="$2"
|
||||
shift 2
|
||||
;;
|
||||
--local-session)
|
||||
local_session="$2"
|
||||
shift 2
|
||||
;;
|
||||
--repo-dir)
|
||||
remote_repo_dir="$2"
|
||||
shift 2
|
||||
;;
|
||||
--workspace)
|
||||
workspace="$2"
|
||||
shift 2
|
||||
;;
|
||||
--codex-image)
|
||||
warn_deprecated "--codex-image is deprecated and ignored; Codex now runs on the host."
|
||||
codex_image="$2"
|
||||
shift 2
|
||||
;;
|
||||
--claude-config)
|
||||
claude_config_dir="$2"
|
||||
shift 2
|
||||
;;
|
||||
--remote-recreate)
|
||||
remote_recreate=true
|
||||
shift
|
||||
;;
|
||||
--recreate)
|
||||
recreate=true
|
||||
shift
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option: $1" >&2
|
||||
usage >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ ${#machines[@]} -eq 0 ]]; then
|
||||
mapfile -t machines < <(zellij_ai_default_machine_specs)
|
||||
fi
|
||||
|
||||
if [[ -z "$workspace" ]]; then
|
||||
echo "--workspace is required for fleet mode." >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
workspace="$(cd "$workspace" && pwd -P)"
|
||||
|
||||
for required in \
|
||||
zellij \
|
||||
ssh \
|
||||
"$script_dir/zellij-ai-common.sh" \
|
||||
"$script_dir/zellij-ai-fleet-bootstrap.sh" \
|
||||
"$script_dir/zellij-ai-remote-tab.sh"
|
||||
do
|
||||
if [[ "$required" == */* ]]; then
|
||||
if [[ ! -x "$required" ]]; then
|
||||
echo "Helper script not executable: $required" >&2
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
zellij_ai_require_command "$required"
|
||||
fi
|
||||
done
|
||||
|
||||
state_dir="$(zellij_ai_fleet_state_dir "$local_session")"
|
||||
tabs_file="$state_dir/tabs.tsv"
|
||||
tabs_created_file="$state_dir/tabs-created"
|
||||
first_layout_file="$state_dir/first-tab.kdl"
|
||||
mkdir -p "$state_dir"
|
||||
: >"$tabs_file"
|
||||
rm -f "$tabs_created_file"
|
||||
|
||||
bootstrap_path="$(zellij_ai_kdl_escape "$script_dir/zellij-ai-fleet-bootstrap.sh")"
|
||||
|
||||
first_label=""
|
||||
first_wrapper=""
|
||||
seen_labels='|'
|
||||
machine_index=0
|
||||
|
||||
for machine_spec in "${machines[@]}"; do
|
||||
if ! parsed_spec="$(zellij_ai_parse_machine_spec "$machine_spec")"; then
|
||||
echo "Invalid machine spec: $machine_spec" >&2
|
||||
exit 2
|
||||
fi
|
||||
IFS=$'\t' read -r machine_label machine_target <<<"$parsed_spec"
|
||||
|
||||
if [[ "$seen_labels" == *"|${machine_label}|"* ]]; then
|
||||
echo "Duplicate machine label: $machine_label" >&2
|
||||
exit 2
|
||||
fi
|
||||
seen_labels+="${machine_label}|"
|
||||
|
||||
wrapper_path="$state_dir/machine-${machine_index}.sh"
|
||||
layout_path="$state_dir/machine-${machine_index}.kdl"
|
||||
|
||||
wrapper_cmd=(
|
||||
"$script_dir/zellij-ai-remote-tab.sh"
|
||||
--label "$machine_label"
|
||||
--target "$machine_target"
|
||||
--session "$remote_session"
|
||||
--repo-dir "$remote_repo_dir"
|
||||
)
|
||||
|
||||
if [[ -n "$workspace" ]]; then
|
||||
wrapper_cmd+=(--workspace "$workspace")
|
||||
fi
|
||||
if [[ -n "$codex_image" ]]; then
|
||||
wrapper_cmd+=(--codex-image "$codex_image")
|
||||
fi
|
||||
if [[ -n "$claude_config_dir" ]]; then
|
||||
wrapper_cmd+=(--claude-config "$claude_config_dir")
|
||||
fi
|
||||
if $remote_recreate; then
|
||||
wrapper_cmd+=(--remote-recreate)
|
||||
fi
|
||||
|
||||
printf -v wrapper_exec '%q ' "${wrapper_cmd[@]}"
|
||||
wrapper_exec="${wrapper_exec% }"
|
||||
|
||||
cat >"$wrapper_path" <<EOF
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
exec $wrapper_exec
|
||||
EOF
|
||||
chmod +x "$wrapper_path"
|
||||
|
||||
wrapper_path_escaped="$(zellij_ai_kdl_escape "$wrapper_path")"
|
||||
cat >"$layout_path" <<EOF
|
||||
layout {
|
||||
pane size=1 borderless=true {
|
||||
plugin location="tab-bar"
|
||||
}
|
||||
pane command="$wrapper_path_escaped"
|
||||
pane size=2 borderless=true {
|
||||
plugin location="status-bar"
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
if [[ $machine_index -eq 0 ]]; then
|
||||
first_label="$machine_label"
|
||||
first_wrapper="$wrapper_path"
|
||||
else
|
||||
printf '%s\t%s\t%s\n' "$machine_label" "$layout_path" "$repo_dir" >>"$tabs_file"
|
||||
fi
|
||||
|
||||
machine_index=$((machine_index + 1))
|
||||
done
|
||||
|
||||
if [[ -z "$first_label" || -z "$first_wrapper" ]]; then
|
||||
echo "No machine tabs were generated" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cat >"$first_layout_file" <<EOF
|
||||
layout {
|
||||
pane size=1 borderless=true {
|
||||
plugin location="tab-bar"
|
||||
}
|
||||
pane command="$bootstrap_path"
|
||||
pane size=2 borderless=true {
|
||||
plugin location="status-bar"
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
export ZELLIJ_AI_FLEET_TABS_FILE="$tabs_file"
|
||||
export ZELLIJ_AI_FLEET_CREATED_FILE="$tabs_created_file"
|
||||
export ZELLIJ_AI_FLEET_CURRENT_LABEL="$first_label"
|
||||
export ZELLIJ_AI_FLEET_CURRENT_WRAPPER="$first_wrapper"
|
||||
|
||||
if $recreate && zellij_ai_session_exists "$local_session"; then
|
||||
zellij kill-session "$local_session" >/dev/null 2>&1 || true
|
||||
fi
|
||||
|
||||
if zellij_ai_session_exists "$local_session"; then
|
||||
exec zellij attach "$local_session"
|
||||
fi
|
||||
|
||||
exec zellij --new-session-with-layout "$first_layout_file" --session "$local_session"
|
||||
export CONSTANT_SCRIPT_NAME="$(basename "$0")"
|
||||
exec "$script_dir/constant-tmux-fleet.sh" "$@"
|
||||
|
||||
@@ -8,8 +8,8 @@ while [[ -L "$script_source" ]]; do
|
||||
[[ "$script_source" != /* ]] && script_source="$script_dir/$script_source"
|
||||
done
|
||||
script_dir="$(cd "$(dirname "$script_source")" && pwd -P)"
|
||||
if [[ -f "$script_dir/zellij-ai-common.sh" ]]; then
|
||||
source "$script_dir/zellij-ai-common.sh"
|
||||
if [[ -f "$script_dir/constant-common.sh" ]]; then
|
||||
source "$script_dir/constant-common.sh"
|
||||
else
|
||||
zellij_ai_default_repo_dir() {
|
||||
printf '%s\n' '$HOME/constant'
|
||||
@@ -273,7 +273,7 @@ run_check() {
|
||||
print_status repo_dir "$repo_dir"
|
||||
print_status codex_home "$codex_home"
|
||||
|
||||
for binary in bash git zellij node npm uv claude codex copilot vibe; do
|
||||
for binary in bash git tmux node npm uv claude codex copilot vibe; do
|
||||
if command -v "$binary" >/dev/null 2>&1; then
|
||||
print_status "$binary" "$(command -v "$binary")"
|
||||
else
|
||||
@@ -310,7 +310,7 @@ run_check() {
|
||||
|
||||
install_darwin() {
|
||||
ensure_homebrew
|
||||
brew install git zellij node uv
|
||||
brew install git tmux node uv
|
||||
}
|
||||
|
||||
install_linux_ubuntu() {
|
||||
@@ -325,12 +325,8 @@ install_linux_ubuntu() {
|
||||
run_root apt-get install -y npm
|
||||
fi
|
||||
|
||||
if ! command -v zellij >/dev/null 2>&1; then
|
||||
if command -v snap >/dev/null 2>&1; then
|
||||
run_root snap install zellij --classic
|
||||
else
|
||||
run_root apt-get install -y zellij
|
||||
fi
|
||||
if ! command -v tmux >/dev/null 2>&1; then
|
||||
run_root apt-get install -y tmux
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -354,8 +350,14 @@ install_linux_photon() {
|
||||
run_root tdnf install -y "${packages[@]}"
|
||||
fi
|
||||
|
||||
if ! command -v zellij >/dev/null 2>&1; then
|
||||
fail "zellij is missing on Photon OS and no native install path is scripted here."
|
||||
if ! command -v tmux >/dev/null 2>&1; then
|
||||
if command -v tdnf >/dev/null 2>&1; then
|
||||
run_root tdnf install -y tmux
|
||||
fi
|
||||
fi
|
||||
|
||||
if ! command -v tmux >/dev/null 2>&1; then
|
||||
fail "tmux is missing on Photon OS and no native install path is scripted here."
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
@@ -8,22 +8,23 @@ while [[ -L "$script_source" ]]; do
|
||||
[[ "$script_source" != /* ]] && script_source="$script_dir/$script_source"
|
||||
done
|
||||
script_dir="$(cd "$(dirname "$script_source")" && pwd -P)"
|
||||
source "$script_dir/zellij-ai-common.sh"
|
||||
source "$script_dir/constant-common.sh"
|
||||
|
||||
warn_deprecated() {
|
||||
printf 'Warning: %s\n' "$*" >&2
|
||||
}
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage: zellij-ai-remote-tab.sh [options]
|
||||
local script_name="${CONSTANT_SCRIPT_NAME:-$(basename "$0")}"
|
||||
cat <<EOF
|
||||
Usage: ${script_name} [options]
|
||||
|
||||
Open or attach the local AI Zellij session for one machine.
|
||||
Open or attach the local Constant machine session for one machine.
|
||||
|
||||
Options:
|
||||
--label NAME Display label for logs and tab naming
|
||||
--target TARGET SSH target, or "local" for the current machine
|
||||
--session NAME Remote/local Zellij session name
|
||||
--session NAME Remote/local Constant tmux session name
|
||||
default: constant
|
||||
--repo-dir DIR Repository path on the target machine
|
||||
default: $HOME/constant
|
||||
|
||||
+2
-226
@@ -8,230 +8,6 @@ while [[ -L "$script_source" ]]; do
|
||||
[[ "$script_source" != /* ]] && script_source="$script_dir/$script_source"
|
||||
done
|
||||
script_dir="$(cd "$(dirname "$script_source")" && pwd -P)"
|
||||
repo_dir="$(cd "$script_dir/.." && pwd -P)"
|
||||
source "$script_dir/zellij-ai-common.sh"
|
||||
|
||||
usage() {
|
||||
local script_name="${CONSTANT_SCRIPT_NAME:-$(basename "$0")}"
|
||||
cat <<EOF
|
||||
Usage: ${script_name} [options]
|
||||
|
||||
Start a 4-pane Constant machine session:
|
||||
- left pane: Claude on the host
|
||||
- top-right pane: Codex on the host
|
||||
- middle-right pane: Copilot CLI on the host
|
||||
- bottom-right pane: Mistral Vibe on the host
|
||||
|
||||
Options:
|
||||
--workspace DIR Workspace used by all panes
|
||||
default: current directory
|
||||
--session NAME Session name
|
||||
default: $(zellij_ai_default_session)
|
||||
--codex-home DIR Persistent CODEX_HOME for the Codex pane
|
||||
default: $(zellij_ai_default_codex_home)
|
||||
--codex-label LABEL Display label for the Codex pane
|
||||
default: codex
|
||||
--copilot-label LABEL Display label for the Copilot pane
|
||||
default: copilot
|
||||
--vibe-label LABEL Display label for the Vibe pane
|
||||
default: vibe
|
||||
--claude-config DIR Optional CLAUDE_CONFIG_DIR override for the Claude pane
|
||||
--zellij-config-dir DIR
|
||||
Optional isolated Zellij config dir for session creation
|
||||
default: a fresh temporary config dir per new session
|
||||
--codex-image IMAGE Deprecated, ignored
|
||||
--codex1-home DIR Deprecated alias for --codex-home
|
||||
--codex2-home DIR Deprecated, ignored
|
||||
--codex1-label LABEL Deprecated alias for --codex-label
|
||||
--codex2-label LABEL Deprecated, ignored
|
||||
--recreate Recreate the session and purge stale Zellij state first
|
||||
-h, --help Show this help
|
||||
EOF
|
||||
}
|
||||
|
||||
warn_deprecated() {
|
||||
printf 'Warning: %s\n' "$*" >&2
|
||||
}
|
||||
|
||||
workspace="$PWD"
|
||||
session="$(zellij_ai_default_session)"
|
||||
codex_home="$(zellij_ai_default_codex_home)"
|
||||
codex_label="codex"
|
||||
copilot_label="copilot"
|
||||
vibe_label="vibe"
|
||||
claude_config_dir=""
|
||||
zellij_config_dir=""
|
||||
recreate=false
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--workspace)
|
||||
workspace="$2"
|
||||
shift 2
|
||||
;;
|
||||
--session)
|
||||
session="$2"
|
||||
shift 2
|
||||
;;
|
||||
--codex-home)
|
||||
codex_home="$2"
|
||||
shift 2
|
||||
;;
|
||||
--codex-label)
|
||||
codex_label="$2"
|
||||
shift 2
|
||||
;;
|
||||
--copilot-label)
|
||||
copilot_label="$2"
|
||||
shift 2
|
||||
;;
|
||||
--vibe-label)
|
||||
vibe_label="$2"
|
||||
shift 2
|
||||
;;
|
||||
--codex-image)
|
||||
warn_deprecated "--codex-image is deprecated and ignored; Codex now runs on the host."
|
||||
shift 2
|
||||
;;
|
||||
--codex1-home)
|
||||
warn_deprecated "--codex1-home is deprecated; use --codex-home."
|
||||
codex_home="$2"
|
||||
shift 2
|
||||
;;
|
||||
--codex2-home)
|
||||
warn_deprecated "--codex2-home is deprecated and ignored."
|
||||
shift 2
|
||||
;;
|
||||
--codex1-label)
|
||||
warn_deprecated "--codex1-label is deprecated; use --codex-label."
|
||||
codex_label="$2"
|
||||
shift 2
|
||||
;;
|
||||
--codex2-label)
|
||||
warn_deprecated "--codex2-label is deprecated and ignored."
|
||||
shift 2
|
||||
;;
|
||||
--claude-config)
|
||||
claude_config_dir="$2"
|
||||
shift 2
|
||||
;;
|
||||
--zellij-config-dir)
|
||||
zellij_config_dir="$2"
|
||||
shift 2
|
||||
;;
|
||||
--recreate)
|
||||
recreate=true
|
||||
shift
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option: $1" >&2
|
||||
usage >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
workspace="$(cd "$workspace" && pwd -P)"
|
||||
codex_home="$(mkdir -p "$(zellij_ai_expand_home_path "$codex_home")" && cd "$(zellij_ai_expand_home_path "$codex_home")" && pwd -P)"
|
||||
|
||||
machine_name="$(zellij_ai_current_machine_name)"
|
||||
state_dir="$(zellij_ai_session_state_dir "$session")"
|
||||
bus_dir="$state_dir/bus"
|
||||
bootstrap_file="$state_dir/bootstrapped"
|
||||
layout_file="$state_dir/layout.kdl"
|
||||
clipboard_config_file="$state_dir/zellij.config.kdl"
|
||||
|
||||
if [[ ! -d "$workspace" ]]; then
|
||||
echo "Workspace not found: $workspace" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for required in \
|
||||
"$script_dir/zellij-ai-claude-pane.sh" \
|
||||
"$script_dir/zellij-ai-codex-pane.sh" \
|
||||
"$script_dir/zellij-ai-copilot-pane.sh" \
|
||||
"$script_dir/zellij-ai-vibe-pane.sh" \
|
||||
"$script_dir/zellij-ai-bootstrap.sh" \
|
||||
"$script_dir/zellij-ai-common.sh"
|
||||
do
|
||||
if [[ ! -x "$required" ]]; then
|
||||
echo "Helper script not executable: $required" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
mkdir -p "$bus_dir/messages"
|
||||
|
||||
if [[ "${ZELLIJ_AI_FORCE_OSC52:-false}" == "true" || "${ZELLIJ_AI_FORCE_OSC52:-0}" == "1" ]]; then
|
||||
cat >"$clipboard_config_file" <<'EOF'
|
||||
copy_clipboard "system"
|
||||
EOF
|
||||
elif [[ "$(uname -s)" == "Darwin" && -x /usr/bin/pbcopy ]]; then
|
||||
cat >"$clipboard_config_file" <<'EOF'
|
||||
copy_command "pbcopy"
|
||||
copy_clipboard "system"
|
||||
EOF
|
||||
else
|
||||
cat >"$clipboard_config_file" <<'EOF'
|
||||
copy_clipboard "system"
|
||||
EOF
|
||||
fi
|
||||
|
||||
export ZELLIJ_AI_WORKSPACE="$workspace"
|
||||
export ZELLIJ_AI_CODEX_HOME="$codex_home"
|
||||
export ZELLIJ_AI_CODEX_LABEL="$codex_label"
|
||||
export ZELLIJ_AI_COPILOT_LABEL="$copilot_label"
|
||||
export ZELLIJ_AI_VIBE_LABEL="$vibe_label"
|
||||
export ZELLIJ_AI_MAIN_CODEX_CONFIG="$HOME/.codex/config.toml"
|
||||
export ZELLIJ_AI_BOOTSTRAP_FILE="$bootstrap_file"
|
||||
export ZELLIJ_AI_REPO_DIR="$repo_dir"
|
||||
export ZELLIJ_AI_SESSION="$session"
|
||||
export ZELLIJ_AI_STATE_DIR="$state_dir"
|
||||
export ZELLIJ_AI_BUS_DIR="$bus_dir"
|
||||
export ZELLIJ_AI_MACHINE_NAME="$machine_name"
|
||||
|
||||
if [[ -n "$claude_config_dir" ]]; then
|
||||
export ZELLIJ_AI_CLAUDE_CONFIG_DIR="$claude_config_dir"
|
||||
fi
|
||||
|
||||
zellij_attach_cmd=(zellij --config "$clipboard_config_file")
|
||||
|
||||
if $recreate && zellij_ai_session_exists "$session"; then
|
||||
zellij delete-session -f "$session" >/dev/null 2>&1 || true
|
||||
fi
|
||||
|
||||
if zellij_ai_session_exists "$session"; then
|
||||
exec "${zellij_attach_cmd[@]}" attach "$session"
|
||||
fi
|
||||
|
||||
zellij delete-session "$session" >/dev/null 2>&1 || true
|
||||
mkdir -p "$state_dir"
|
||||
rm -f "$bootstrap_file"
|
||||
|
||||
bootstrap_path="$(zellij_ai_kdl_escape "$script_dir/zellij-ai-bootstrap.sh")"
|
||||
cat >"$layout_file" <<EOF
|
||||
layout {
|
||||
tab name="Constant" {
|
||||
pane size=1 borderless=true {
|
||||
plugin location="tab-bar"
|
||||
}
|
||||
pane command="$bootstrap_path"
|
||||
pane size=2 borderless=true {
|
||||
plugin location="status-bar"
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
if [[ -z "$zellij_config_dir" ]]; then
|
||||
zellij_config_dir="$(mktemp -d "${TMPDIR:-/tmp}/constant-zellij-${session}.XXXXXX")"
|
||||
else
|
||||
zellij_config_dir="$(zellij_ai_expand_home_path "$zellij_config_dir")"
|
||||
mkdir -p "$zellij_config_dir"
|
||||
fi
|
||||
|
||||
exec zellij --config "$clipboard_config_file" --config-dir "$zellij_config_dir" --new-session-with-layout "$layout_file" --session "$session"
|
||||
export CONSTANT_SCRIPT_NAME="$(basename "$0")"
|
||||
exec "$script_dir/constant-tmux-machine.sh" "$@"
|
||||
|
||||
@@ -8,7 +8,7 @@ while [[ -L "$script_source" ]]; do
|
||||
[[ "$script_source" != /* ]] && script_source="$script_dir/$script_source"
|
||||
done
|
||||
script_dir="$(cd "$(dirname "$script_source")" && pwd -P)"
|
||||
source "$script_dir/zellij-ai-common.sh"
|
||||
source "$script_dir/constant-common.sh"
|
||||
|
||||
workspace="${ZELLIJ_AI_WORKSPACE:-$PWD}"
|
||||
machine_name="${ZELLIJ_AI_MACHINE_NAME:-unknown}"
|
||||
|
||||
Reference in New Issue
Block a user