diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 0000000..28a362c
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,80 @@
+name: Release & Update Homebrew Formula
+
+on:
+ release:
+ types: [published]
+
+permissions:
+ contents: write
+
+jobs:
+ update-formula:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ ref: main
+
+ - name: Get release tag
+ id: tag
+ run: echo "version=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT"
+
+ - name: Download source tarball and compute SHA256
+ id: sha
+ run: |
+ TARBALL_URL="https://github.com/${{ github.repository }}/archive/refs/tags/${GITHUB_REF_NAME}.tar.gz"
+ SHA256=$(curl -sL "$TARBALL_URL" | shasum -a 256 | awk '{print $1}')
+ echo "sha256=$SHA256" >> "$GITHUB_OUTPUT"
+ echo "url=$TARBALL_URL" >> "$GITHUB_OUTPUT"
+
+ - name: Update formula version and SHA256
+ run: |
+ sed -i \
+ -e 's|url "https://github.com/.*/archive/refs/tags/.*\.tar\.gz"|url "${{ steps.sha.outputs.url }}"|' \
+ -e 's|sha256 ".*"|sha256 "${{ steps.sha.outputs.sha256 }}"|' \
+ Formula/agent-pulse.rb
+
+ # Update only the first sha256 (the source tarball, not resource hashes)
+ # The sed above replaced all sha256 lines — restore the resource hashes
+ git checkout -- Formula/agent-pulse.rb
+
+ # Now do a targeted update: only the url and the sha256 on the line after it
+ python3 - <<'PYEOF'
+ import re, sys
+
+ with open("Formula/agent-pulse.rb") as f:
+ content = f.read()
+
+ # Update the source url
+ content = re.sub(
+ r'( url )"https://github\.com/.*/archive/refs/tags/.*\.tar\.gz"',
+ rf'\1"${{ steps.sha.outputs.url }}"',
+ content,
+ count=1,
+ )
+
+ # Update the source sha256 (the one right after the url line, before license)
+ content = re.sub(
+ r'( url "https://github\.com/.*\.tar\.gz"\n )sha256 ".*?"',
+ rf'\g<1>sha256 "${{ steps.sha.outputs.sha256 }}"',
+ content,
+ count=1,
+ )
+
+ with open("Formula/agent-pulse.rb", "w") as f:
+ f.write(content)
+ PYEOF
+
+ - name: Verify formula syntax
+ run: ruby -c Formula/agent-pulse.rb
+
+ - name: Commit and push updated formula
+ run: |
+ git config user.name "github-actions[bot]"
+ git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
+ git add Formula/agent-pulse.rb
+ git diff --cached --quiet && echo "No changes to commit" && exit 0
+ git commit -m "Update Homebrew formula for ${GITHUB_REF_NAME}
+
+ Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>"
+ git push origin main
diff --git a/Formula/agent-pulse.rb b/Formula/agent-pulse.rb
new file mode 100644
index 0000000..81b9df9
--- /dev/null
+++ b/Formula/agent-pulse.rb
@@ -0,0 +1,70 @@
+class AgentPulse < Formula
+ include Language::Python::Virtualenv
+
+ desc "Real-time terminal dashboard for monitoring GitHub Copilot CLI sessions and agents"
+ homepage "https://github.com/DUBSOpenHub/copilot-cli-agent-pulse"
+ url "https://github.com/DUBSOpenHub/copilot-cli-agent-pulse/archive/refs/tags/v1.0.0.tar.gz"
+ sha256 "PLACEHOLDER"
+ license "MIT"
+
+ depends_on "python@3.12"
+
+ resource "linkify-it-py" do
+ url "https://files.pythonhosted.org/packages/2e/c9/06ea13676ef354f0af6169587ae292d3e2406e212876a413bf9eece4eb23/linkify_it_py-2.1.0.tar.gz"
+ sha256 "43360231720999c10e9328dc3691160e27a718e280673d444c38d7d3aaa3b98b"
+ end
+
+ resource "markdown-it-py" do
+ url "https://files.pythonhosted.org/packages/5b/f5/4ec618ed16cc4f8fb3b701563655a69816155e79e24a17b651541804721d/markdown_it_py-4.0.0.tar.gz"
+ sha256 "cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3"
+ end
+
+ resource "mdit-py-plugins" do
+ url "https://files.pythonhosted.org/packages/b2/fd/a756d36c0bfba5f6e39a1cdbdbfdd448dc02692467d83816dff4592a1ebc/mdit_py_plugins-0.5.0.tar.gz"
+ sha256 "f4918cb50119f50446560513a8e311d574ff6aaed72606ddae6d35716fe809c6"
+ end
+
+ resource "mdurl" do
+ url "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz"
+ sha256 "bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"
+ end
+
+ resource "platformdirs" do
+ url "https://files.pythonhosted.org/packages/9f/4a/0883b8e3802965322523f0b200ecf33d31f10991d0401162f4b23c698b42/platformdirs-4.9.6.tar.gz"
+ sha256 "3bfa75b0ad0db84096ae777218481852c0ebc6c727b3168c1b9e0118e458cf0a"
+ end
+
+ resource "pygments" do
+ url "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz"
+ sha256 "6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f"
+ end
+
+ resource "rich" do
+ url "https://files.pythonhosted.org/packages/c0/8f/0722ca900cc807c13a6a0c696dacf35430f72e0ec571c4275d2371fca3e9/rich-15.0.0.tar.gz"
+ sha256 "edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36"
+ end
+
+ resource "textual" do
+ url "https://files.pythonhosted.org/packages/cf/2f/d44f0f12b3ddb1f0b88f7775652e99c6b5a43fd733badf4ce064bdbfef4a/textual-8.2.3.tar.gz"
+ sha256 "beea7b86b03b03558a2224f0cc35252e60ef8b0c4353b117b2f40972902d976a"
+ end
+
+ resource "typing_extensions" do
+ url "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz"
+ sha256 "0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466"
+ end
+
+ resource "uc-micro-py" do
+ url "https://files.pythonhosted.org/packages/78/67/9a363818028526e2d4579334460df777115bdec1bb77c08f9db88f6389f2/uc_micro_py-2.0.0.tar.gz"
+ sha256 "c53691e495c8db60e16ffc4861a35469b0ba0821fe409a8a7a0a71864d33a811"
+ end
+
+ def install
+ virtualenv_install_with_resources
+ end
+
+ test do
+ assert_match "Agent Pulse", shell_output("#{bin}/agent-pulse --help")
+ assert_match "{", shell_output("#{bin}/agent-pulse --export")
+ end
+end
diff --git a/README.md b/README.md
index eb7af91..75dce19 100644
--- a/README.md
+++ b/README.md
@@ -6,11 +6,20 @@
### 🚀 Install & Launch
+**Homebrew (recommended on macOS):**
+
+```bash
+brew tap DUBSOpenHub/copilot-cli-agent-pulse
+brew install agent-pulse
+```
+
+**Quick installer (any platform):**
+
```bash
curl -fsSL https://raw.githubusercontent.com/DUBSOpenHub/copilot-cli-agent-pulse/main/quickstart.sh | bash
```
-Then just type `agentpulse` — the dashboard opens in a new terminal window automatically.
+Then just type `agentpulse` or `agent-pulse` to launch the dashboard. Add `--new-window` to open it in a separate window of your current terminal emulator.
@@ -73,7 +82,7 @@ alias agentpulse='~/copilot-cli-agent-pulse/start.sh'
alias agentdashboard='~/copilot-cli-agent-pulse/start.sh'
```
-Then just type **`agentpulse`** or **`agentdashboard`** from anywhere — the live dashboard **automatically opens in a new terminal window** so it never blocks your current session.
+Then just type **`agentpulse`** or **`agentdashboard`** from anywhere to launch the dashboard in your current terminal. Use **`--new-window`** to open it in a separate window — it auto-detects your terminal emulator (Ghostty, iTerm, Kitty, WezTerm, Alacritty, Warp, Terminal.app) and works with tmux.
---
@@ -192,7 +201,7 @@ copilot-cli-agent-pulse/
├── agent_pulse.tcss # Textual CSS stylesheet
├── pyproject.toml # Python packaging + entry point
├── requirements.txt # Python dependencies (rich, textual)
-├── start.sh # Launcher (auto-opens in new terminal window)
+├── start.sh # Launcher (--new-window for separate window)
├── quickstart.sh # One-command installer
├── site/ # Showcase website (GitHub Pages)
│ └── index.html
diff --git a/quickstart.sh b/quickstart.sh
index 9088733..61c3c49 100755
--- a/quickstart.sh
+++ b/quickstart.sh
@@ -35,6 +35,7 @@ echo " ✅ Installed to $DEST"
echo ""
# Auto-add shell aliases if not already present
+FISH_CONFIG="$HOME/.config/fish/config.fish"
SHELL_RC=""
if [ -f "$HOME/.zshrc" ]; then
SHELL_RC="$HOME/.zshrc"
@@ -42,18 +43,37 @@ elif [ -f "$HOME/.bashrc" ]; then
SHELL_RC="$HOME/.bashrc"
fi
+ALIASES_ADDED=0
+
+# bash/zsh aliases
if [ -n "$SHELL_RC" ] && ! grep -q 'alias agentpulse=' "$SHELL_RC" 2>/dev/null; then
echo "" >> "$SHELL_RC"
- echo "# Agent Pulse — auto-opens live dashboard in a new terminal window" >> "$SHELL_RC"
+ echo "# Agent Pulse — live terminal dashboard" >> "$SHELL_RC"
echo "alias agentpulse='~/copilot-cli-agent-pulse/start.sh'" >> "$SHELL_RC"
echo "alias agentdashboard='~/copilot-cli-agent-pulse/start.sh'" >> "$SHELL_RC"
echo " 🔗 Added 'agentpulse' and 'agentdashboard' aliases to $(basename "$SHELL_RC")"
-else
+ ALIASES_ADDED=1
+fi
+
+# fish aliases
+if [ -f "$FISH_CONFIG" ] || echo "$SHELL" | grep -q fish; then
+ mkdir -p "$(dirname "$FISH_CONFIG")"
+ if ! grep -q 'alias agentpulse' "$FISH_CONFIG" 2>/dev/null; then
+ echo "" >> "$FISH_CONFIG"
+ echo "# Agent Pulse — live terminal dashboard" >> "$FISH_CONFIG"
+ echo "alias agentpulse '~/copilot-cli-agent-pulse/start.sh'" >> "$FISH_CONFIG"
+ echo "alias agentdashboard '~/copilot-cli-agent-pulse/start.sh'" >> "$FISH_CONFIG"
+ echo " 🔗 Added 'agentpulse' and 'agentdashboard' aliases to config.fish"
+ ALIASES_ADDED=1
+ fi
+fi
+
+if [ "$ALIASES_ADDED" -eq 0 ]; then
echo " 🔗 Aliases already configured."
fi
echo ""
-echo " Launch it (opens in a new terminal window):"
+echo " Launch it:"
echo " agentpulse"
echo " agentdashboard"
echo ""
diff --git a/start.sh b/start.sh
index 2cc902f..47954ac 100755
--- a/start.sh
+++ b/start.sh
@@ -1,10 +1,22 @@
#!/bin/bash
# Agent Pulse — Quick launcher
-# Opens the live dashboard in a new terminal window (macOS)
+# Runs the dashboard in the current terminal by default.
+# Use --new-window to open in a new window of your current terminal emulator.
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
VENV="$SCRIPT_DIR/.venv"
+# Parse --new-window flag (pass everything else through to agent_pulse.py)
+NEW_WINDOW=0
+ARGS=()
+for arg in "$@"; do
+ if [ "$arg" = "--new-window" ]; then
+ NEW_WINDOW=1
+ else
+ ARGS+=("$arg")
+ fi
+done
+
# Create venv if missing
if [ ! -d "$VENV" ]; then
echo "🐍 Creating virtual environment..."
@@ -17,28 +29,114 @@ if ! "$VENV/bin/python" -c "import textual" 2>/dev/null; then
"$VENV/bin/pip" install --quiet -r "$SCRIPT_DIR/requirements.txt"
fi
-# If already running inside a spawned terminal, just run directly
-if [ "$AGENT_PULSE_SPAWNED" = "1" ]; then
- exec "$VENV/bin/python" "$SCRIPT_DIR/agent_pulse.py" "$@"
+# Default: run in current terminal
+if [ "$NEW_WINDOW" -eq 0 ] || [ "$AGENT_PULSE_SPAWNED" = "1" ]; then
+ exec "$VENV/bin/python" "$SCRIPT_DIR/agent_pulse.py" "${ARGS[@]}"
fi
-# Open dashboard in a new terminal window
-CMD="export AGENT_PULSE_SPAWNED=1; cd '$SCRIPT_DIR' && '$VENV/bin/python' '$SCRIPT_DIR/agent_pulse.py' $*"
-
-if command -v osascript &>/dev/null; then
- # macOS — open a new Terminal.app window
- osascript -e "tell application \"Terminal\"
- activate
- do script \"$CMD\"
- end tell" &>/dev/null
- echo "⚡ Agent Pulse launched in a new Terminal window."
-elif command -v gnome-terminal &>/dev/null; then
- gnome-terminal -- bash -c "$CMD; exec bash" &>/dev/null &
- echo "⚡ Agent Pulse launched in a new terminal window."
-elif command -v xterm &>/dev/null; then
- xterm -e bash -c "$CMD" &>/dev/null &
- echo "⚡ Agent Pulse launched in xterm."
-else
- # Fallback — run in current terminal
- exec "$VENV/bin/python" "$SCRIPT_DIR/agent_pulse.py" "$@"
+# --new-window: open in a new window/pane
+CMD="export AGENT_PULSE_SPAWNED=1; cd '$SCRIPT_DIR' && '$VENV/bin/python' '$SCRIPT_DIR/agent_pulse.py' ${ARGS[*]}"
+
+# tmux — new window in the current session
+if [ -n "$TMUX" ]; then
+ tmux new-window -n "AgentPulse" "bash -c '$CMD'"
+ echo "⚡ Agent Pulse launched in a new tmux window."
+ exit 0
fi
+
+# Detect the running terminal emulator (macOS)
+TERM_APP=""
+if [ "$(uname)" = "Darwin" ]; then
+ TERM_BUNDLE=$(__CFBundleIdentifier="" && osascript -e 'tell application "System Events" to get bundle identifier of (first process whose frontmost is true)' 2>/dev/null)
+ case "$TERM_BUNDLE" in
+ com.mitchellh.ghostty) TERM_APP="ghostty" ;;
+ com.googlecode.iterm2) TERM_APP="iterm" ;;
+ io.alacritty) TERM_APP="alacritty" ;;
+ net.kovidgoyal.kitty) TERM_APP="kitty" ;;
+ com.github.wez.wezterm) TERM_APP="wezterm" ;;
+ dev.warp.Warp-Stable|dev.warp*) TERM_APP="warp" ;;
+ com.apple.Terminal) TERM_APP="terminal" ;;
+ esac
+fi
+
+case "$TERM_APP" in
+ ghostty)
+ # Ghostty — open a new window via its CLI
+ if command -v ghostty &>/dev/null; then
+ ghostty -e bash -c "$CMD" &
+ else
+ osascript -e "tell application \"Ghostty\" to activate" \
+ -e "tell application \"System Events\" to keystroke \"n\" using command down" &>/dev/null
+ sleep 0.5
+ osascript -e "tell application \"System Events\" to tell process \"Ghostty\" to keystroke \"$CMD
+\"" &>/dev/null
+ fi
+ echo "⚡ Agent Pulse launched in a new Ghostty window."
+ ;;
+ iterm)
+ osascript -e "
+ tell application \"iTerm\"
+ activate
+ create window with default profile command \"bash -c '$CMD'\"
+ end tell" &>/dev/null
+ echo "⚡ Agent Pulse launched in a new iTerm window."
+ ;;
+ kitty)
+ kitty @ launch --type=os-window bash -c "$CMD" 2>/dev/null \
+ || kitty --single-instance bash -c "$CMD" &
+ echo "⚡ Agent Pulse launched in a new Kitty window."
+ ;;
+ wezterm)
+ wezterm cli spawn --new-window -- bash -c "$CMD" 2>/dev/null \
+ || wezterm start -- bash -c "$CMD" &
+ echo "⚡ Agent Pulse launched in a new WezTerm window."
+ ;;
+ alacritty)
+ alacritty -e bash -c "$CMD" &
+ echo "⚡ Agent Pulse launched in a new Alacritty window."
+ ;;
+ warp)
+ osascript -e "
+ tell application \"Warp\"
+ activate
+ end tell
+ tell application \"System Events\" to keystroke \"n\" using command down" &>/dev/null
+ sleep 0.5
+ osascript -e "tell application \"System Events\" to keystroke \"$CMD
+\"" &>/dev/null
+ echo "⚡ Agent Pulse launched in a new Warp window."
+ ;;
+ terminal)
+ osascript -e "
+ tell application \"Terminal\"
+ activate
+ do script \"$CMD\"
+ end tell" &>/dev/null
+ echo "⚡ Agent Pulse launched in a new Terminal window."
+ ;;
+ *)
+ # Linux / fallback detection
+ if command -v ghostty &>/dev/null; then
+ ghostty -e bash -c "$CMD" &
+ echo "⚡ Agent Pulse launched in a new Ghostty window."
+ elif command -v kitty &>/dev/null; then
+ kitty bash -c "$CMD" &
+ echo "⚡ Agent Pulse launched in a new Kitty window."
+ elif command -v wezterm &>/dev/null; then
+ wezterm start -- bash -c "$CMD" &
+ echo "⚡ Agent Pulse launched in a new WezTerm window."
+ elif command -v alacritty &>/dev/null; then
+ alacritty -e bash -c "$CMD" &
+ echo "⚡ Agent Pulse launched in a new Alacritty window."
+ elif command -v gnome-terminal &>/dev/null; then
+ gnome-terminal -- bash -c "$CMD; exec bash" &
+ echo "⚡ Agent Pulse launched in a new terminal window."
+ elif command -v xterm &>/dev/null; then
+ xterm -e bash -c "$CMD" &
+ echo "⚡ Agent Pulse launched in xterm."
+ else
+ echo "⚠️ Could not detect terminal emulator — running in current terminal."
+ exec "$VENV/bin/python" "$SCRIPT_DIR/agent_pulse.py" "${ARGS[@]}"
+ fi
+ ;;
+esac