diff --git a/README.md b/README.md index 9168db0..f6d3d4d 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ Clone the repo only when you want a source checkout for development: ```sh git clone https://github.com/flamerged/agent-watch.git cd agent-watch -./scripts/install-swiftbar.sh "$HOME/SwiftBarPlugins" +./scripts/install-dev-swiftbar.sh "$HOME/SwiftBarPlugins" ``` Release installs show `Update to latest release`, so normal users do not need git. Source checkout installs show the current branch and commit for diagnostics, but hide the menu updater to avoid overwriting checkout-managed files. Development updates should use normal git commands in the checkout. @@ -102,7 +102,8 @@ The plugin also supports a local config file at `~/.config/agent-watch/config.en | `AGENTWATCH_SHOW_BACKEND_ACTIONS` | `0` | Set to `1` to show backend web/log open actions for detected services | | `AGENTWATCH_REPO_DIR` | empty | Optional Agent Watch git checkout for source metadata | | `AGENTWATCH_REPO_URL` | `https://github.com/flamerged/agent-watch` | Project page opened from the menu | -| `AGENTWATCH_RELEASE_ASSET_URL` | `https://github.com/flamerged/agent-watch/releases/latest/download/agent-watch.30s.sh` | Latest release asset URL used by copied-plugin updates | +| `AGENTWATCH_RELEASE_ASSET_URL` | `https://github.com/flamerged/agent-watch/releases/latest/download/agent-watch.30s.sh` | HTTPS latest release asset URL used by copied-plugin updates | +| `AGENTWATCH_UPDATE_LOG` | `$HOME/.cache/agent-watch/update.log` | Update log path | | `AGENTWATCH_INTERESTING_PORTS` | `8000,11434,3000,4000,5000` | Comma-separated TCP listening ports to show | ## Privacy And Security @@ -119,7 +120,7 @@ The default update-check TTL is one day. Set `AGENTWATCH_UPDATE_TTL_SECONDS` to The "Watched Local Ports" section is controlled by `AGENTWATCH_INTERESTING_PORTS`. By default it watches the configured oMLX port, the configured Ollama port, and common local development ports `3000`, `4000`, and `5000`. -The Agent Watch section shows the plugin version, config path, and script path. Release installs also show `Update to latest release`, which downloads the latest release asset and replaces the plugin script without requiring git. If the plugin can detect a git checkout, it instead shows the branch and commit for diagnostics and leaves updates to normal git commands. +The Agent Watch section shows the plugin version, config path, and script path. Release installs also show `Update to latest release`, which runs in the background, logs to `AGENTWATCH_UPDATE_LOG`, downloads the latest release asset, and replaces the plugin script without requiring git. If the plugin can detect a git checkout, it instead shows the branch and commit for diagnostics and leaves updates to normal git commands. Local config files may reveal model names, provider URLs, and project paths in the menu output. Do not screen-share the menu if those are sensitive. diff --git a/bin/agent-watch.30s.sh b/bin/agent-watch.30s.sh index 49cd72b..a6c966d 100755 --- a/bin/agent-watch.30s.sh +++ b/bin/agent-watch.30s.sh @@ -18,6 +18,7 @@ # string(AGENTWATCH_REPO_DIR=""): Optional Agent Watch git checkout for source metadata # string(AGENTWATCH_REPO_URL="https://github.com/flamerged/agent-watch"): Agent Watch repository URL # string(AGENTWATCH_RELEASE_ASSET_URL="https://github.com/flamerged/agent-watch/releases/latest/download/agent-watch.30s.sh"): Latest release asset URL for copied-plugin updates +# string(AGENTWATCH_UPDATE_LOG="~/.cache/agent-watch/update.log"): Update log file path # string(AGENTWATCH_INTERESTING_PORTS="8000,11434,3000,4000,5000"): TCP ports to show # Agent Watch # v0.3.0 # x-release-please-version @@ -162,6 +163,8 @@ SWIFTBAR_PLUGIN_DIR="${AGENTWATCH_SWIFTBAR_PLUGIN_DIR:-$HOME/SwiftBarPlugins}" AGENTWATCH_REPO_DIR="${AGENTWATCH_REPO_DIR:-}" AGENTWATCH_REPO_URL="${AGENTWATCH_REPO_URL:-https://github.com/flamerged/agent-watch}" RELEASE_ASSET_URL="${AGENTWATCH_RELEASE_ASSET_URL:-https://github.com/flamerged/agent-watch/releases/latest/download/agent-watch.30s.sh}" +UPDATE_LOG="${AGENTWATCH_UPDATE_LOG:-$HOME/.cache/agent-watch/update.log}" +UPDATE_LOG="${UPDATE_LOG/#\~/$HOME}" AGENTMEMORY_LOG="${AGENTWATCH_AGENTMEMORY_LOG:-$HOME/local-agentmemory/logs/agentmemory.log}" OMLX_URL="$(strip_slash "${AGENTWATCH_OMLX_URL:-http://127.0.0.1:8000}")" OLLAMA_URL="$(strip_slash "${AGENTWATCH_OLLAMA_URL:-http://127.0.0.1:11434}")" @@ -245,37 +248,59 @@ plugin_version_label() { emit "v${PLUGIN_VERSION}" } +log_update() { + mkdir -p "${UPDATE_LOG:h}" 2>/dev/null || return + builtin print -r -- "[$(date '+%Y-%m-%d %H:%M:%S %z' 2>/dev/null || date)] ${1:-}" >> "$UPDATE_LOG" 2>/dev/null || true +} + +update_message() { + local message="${1:-}" + print "$message" + log_update "$message" +} + update_plugin_from_release() { local repo_root + mkdir -p "${UPDATE_LOG:h}" 2>/dev/null || true + log_update "=== Agent Watch release update started ===" + log_update "Plugin: $PLUGIN_PATH" + log_update "Asset: $RELEASE_ASSET_URL" + repo_root="$(plugin_repo_root)" if [[ -n "$repo_root" && "$PLUGIN_PATH" == "$repo_root"/* ]]; then - print "Plugin appears to be running from a git checkout: $repo_root" - print "Use git commands in the checkout for development updates." + update_message "Plugin appears to be running from a git checkout: $repo_root" + update_message "Use git commands in the checkout for development updates." return 1 fi if ! have "$CURL"; then - print "curl is required to update from the latest release." + update_message "curl is required to update from the latest release." return 1 fi if [[ ! -w "$PLUGIN_PATH" || ! -w "$PLUGIN_DIR" ]]; then - print "Plugin file or directory is not writable: $PLUGIN_PATH" + update_message "Plugin file or directory is not writable: $PLUGIN_PATH" + return 1 + fi + if [[ "$RELEASE_ASSET_URL" != https://* ]]; then + update_message "Refusing non-HTTPS release asset URL: $RELEASE_ASSET_URL" return 1 fi - local tmp first_line content + local tmp first_line content curl_log tmp="${PLUGIN_DIR}/.agent-watch.30s.sh.$$" + curl_log="$UPDATE_LOG" + [[ -d "${UPDATE_LOG:h}" && -w "${UPDATE_LOG:h}" ]] || curl_log="/dev/null" rm -f "$tmp" - print "Downloading latest Agent Watch release asset..." + update_message "Downloading latest Agent Watch release asset..." if ! "$CURL" -fsSL \ --connect-timeout 5 \ --max-time 30 \ --retry 2 \ --retry-delay 1 \ - "$RELEASE_ASSET_URL" -o "$tmp"; then + "$RELEASE_ASSET_URL" -o "$tmp" >> "$curl_log" 2>&1; then rm -f "$tmp" - print "Download failed: $RELEASE_ASSET_URL" + update_message "Download failed: $RELEASE_ASSET_URL" return 1 fi @@ -283,21 +308,21 @@ update_plugin_from_release() { content="$(< "$tmp")" if [[ "$first_line" != "#!/bin/zsh" || "$content" != *"Agent Watch"* || "$content" != *"PLUGIN_VERSION=\""* ]]; then rm -f "$tmp" - print "Downloaded file did not look like an Agent Watch plugin." + update_message "Downloaded file did not look like an Agent Watch plugin." return 1 fi chmod +x "$tmp" || { rm -f "$tmp" - print "Could not mark downloaded plugin executable." + update_message "Could not mark downloaded plugin executable." return 1 } mv "$tmp" "$PLUGIN_PATH" || { rm -f "$tmp" - print "Could not replace plugin file: $PLUGIN_PATH" + update_message "Could not replace plugin file: $PLUGIN_PATH" return 1 } - print "Updated Agent Watch from the latest release." + update_message "Updated Agent Watch from the latest release." } update_cache_age() { @@ -375,6 +400,7 @@ case "$ACTION" in case "${2:-}" in agent-watch-config) write_default_config && open_text_target "$CONFIG_FILE" ;; agent-watch-repo) open_target "$AGENTWATCH_REPO_URL" ;; + update-log) open_text_target "$UPDATE_LOG" ;; plugin-file) open_text_target "$PLUGIN_PATH" ;; codex-config) open_target "$CODEX_CONFIG" ;; claude-sessions) open_target "$CLAUDE_SESSIONS" ;; @@ -957,8 +983,9 @@ print_plugin_rows() { emit "--Git: ${git_summary:-unknown} | font=Menlo" emit "----Use git commands for development updates | color=gray" else - emit "--Update to latest release | bash=$PLUGIN_PATH param1=update-release terminal=true refresh=true" + emit "--Update to latest release | bash=$PLUGIN_PATH param1=update-release terminal=false refresh=true" fi + [[ -f "$UPDATE_LOG" ]] && emit "--Open update log | bash=$PLUGIN_PATH param1=open param2=update-log terminal=false" emit "--Open config file | bash=$PLUGIN_PATH param1=open param2=agent-watch-config terminal=false refresh=true" emit "--Open project page | bash=$PLUGIN_PATH param1=open param2=agent-watch-repo terminal=false" emit "--Open plugin file | bash=$PLUGIN_PATH param1=open param2=plugin-file terminal=false" diff --git a/scripts/check.sh b/scripts/check.sh index 7e1289c..32d8787 100755 --- a/scripts/check.sh +++ b/scripts/check.sh @@ -5,6 +5,8 @@ ROOT="${0:A:h:h}" PLUGIN="$ROOT/bin/agent-watch.30s.sh" zsh -n "$PLUGIN" +zsh -n "$ROOT/scripts/install-swiftbar.sh" +zsh -n "$ROOT/scripts/install-dev-swiftbar.sh" bash -n "$ROOT/scripts/auto-release.sh" for tag in \ @@ -31,6 +33,8 @@ for var in \ 'AGENTWATCH_SHOW_BACKEND_ACTIONS' \ 'AGENTWATCH_REPO_DIR' \ 'AGENTWATCH_REPO_URL' \ + 'AGENTWATCH_RELEASE_ASSET_URL' \ + 'AGENTWATCH_UPDATE_LOG' \ 'AGENTWATCH_INTERESTING_PORTS'; do grep -q ".*$var" "$PLUGIN" done diff --git a/scripts/install-dev-swiftbar.sh b/scripts/install-dev-swiftbar.sh new file mode 100755 index 0000000..1850388 --- /dev/null +++ b/scripts/install-dev-swiftbar.sh @@ -0,0 +1,18 @@ +#!/bin/zsh +set -euo pipefail + +ROOT="${0:A:h:h}" +PLUGIN="$ROOT/bin/agent-watch.30s.sh" +TARGET_DIR="${1:-$HOME/SwiftBarPlugins}" +TARGET="$TARGET_DIR/agent-watch.30s.sh" + +if [[ ! -f "$PLUGIN" || ! -r "$PLUGIN" ]]; then + print -u2 "plugin source not found or unreadable: $PLUGIN" + exit 1 +fi + +mkdir -p "$TARGET_DIR" +ln -sf "$PLUGIN" "$TARGET" +chmod +x "$PLUGIN" + +print "installed dev symlink $TARGET -> $PLUGIN" diff --git a/scripts/install-swiftbar.sh b/scripts/install-swiftbar.sh index f99ffad..9446856 100755 --- a/scripts/install-swiftbar.sh +++ b/scripts/install-swiftbar.sh @@ -1,13 +1,37 @@ #!/bin/zsh set -euo pipefail -ROOT="${0:A:h:h}" -PLUGIN="$ROOT/bin/agent-watch.30s.sh" TARGET_DIR="${1:-$HOME/SwiftBarPlugins}" TARGET="$TARGET_DIR/agent-watch.30s.sh" +RELEASE_ASSET_URL="${AGENTWATCH_RELEASE_ASSET_URL:-https://github.com/flamerged/agent-watch/releases/latest/download/agent-watch.30s.sh}" + +if [[ "$RELEASE_ASSET_URL" != https://* ]]; then + print -u2 "refusing non-HTTPS release asset URL: $RELEASE_ASSET_URL" + exit 1 +fi mkdir -p "$TARGET_DIR" -ln -sf "$PLUGIN" "$TARGET" -chmod +x "$PLUGIN" +tmp="$TARGET_DIR/.agent-watch.30s.sh.$$" +rm -f "$tmp" +trap 'rm -f "$tmp"' EXIT + +curl -fsSL \ + --connect-timeout 5 \ + --max-time 30 \ + --retry 2 \ + --retry-delay 1 \ + "$RELEASE_ASSET_URL" -o "$tmp" + +IFS= read -r first_line < "$tmp" || first_line="" +content="$(< "$tmp")" +if [[ "$first_line" != "#!/bin/zsh" || "$content" != *"Agent Watch"* || "$content" != *"PLUGIN_VERSION=\""* ]]; then + print -u2 "Downloaded file did not look like an Agent Watch plugin." + exit 1 +fi + +chmod +x "$tmp" +rm -f "$TARGET" +mv "$tmp" "$TARGET" +trap - EXIT print "installed $TARGET"