From 6fb5ab9ad653d2e88a2687a73b9f4793ce3e62c0 Mon Sep 17 00:00:00 2001 From: Franco Pellicciotti Date: Fri, 15 May 2026 23:49:30 -0400 Subject: [PATCH] clean: remove obsolete standalone shell scripts and old js layout engine --- Rescue Windows.sh | 9 -- layout-menubar.sh | 45 --------- layout_engine.js | 201 ------------------------------------- load-layout.sh | 22 ---- restore-layout.sh | 9 -- save-layout.sh | 22 ---- script-command.template.sh | 17 ---- select-layout-menu.sh | 15 --- trigger-monocle.sh | 20 ---- workspace-status.sh | 24 +++++ 10 files changed, 24 insertions(+), 360 deletions(-) delete mode 100755 Rescue Windows.sh delete mode 100755 layout-menubar.sh delete mode 100755 layout_engine.js delete mode 100755 load-layout.sh delete mode 100755 restore-layout.sh delete mode 100755 save-layout.sh delete mode 100755 script-command.template.sh delete mode 100755 select-layout-menu.sh delete mode 100755 trigger-monocle.sh create mode 100755 workspace-status.sh diff --git a/Rescue Windows.sh b/Rescue Windows.sh deleted file mode 100755 index 265692e..0000000 --- a/Rescue Windows.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -# @raycast.schemaVersion 1 -# @raycast.title Rescue Windows -# @raycast.mode compact -# @raycast.packageName Window Management - -OUTPUT=$(/opt/homebrew/bin/node $HOME/Developer/raycast-scripts/layout_engine.js rescue) -echo "$OUTPUT" \ No newline at end of file diff --git a/layout-menubar.sh b/layout-menubar.sh deleted file mode 100755 index 6a88583..0000000 --- a/layout-menubar.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/bin/bash - -# @raycast.schemaVersion 1 -# @raycast.title Window Layout Manager -# @raycast.mode menu-bar -# @raycast.packageName Window Management -# @raycast.icon ๐Ÿ’  -# @raycast.interval 1s - -LAYOUT_FILE="$HOME/.hammerspoon/saved_layout.json" -STATE_FILE="/tmp/raycast_layout_state.json" - -# Initialize state if missing -if [ ! -f "$STATE_FILE" ]; then - echo '{"countdown":300,"lastSaved":"Never"}' > "$STATE_FILE" -fi - -# Load current state safely -COUNTDOWN=$(osascript -e 'tell application "System Events" to get value of property list item "countdown" of property list file "'"$STATE_FILE"'"' 2>/dev/null || echo "300") -LAST_SAVED=$(osascript -e 'tell application "System Events" to get value of property list item "lastSaved" of property list file "'"$STATE_FILE"'"' 2>/dev/null || echo "Never") - -# Handle countdown decrement -COUNTDOWN=$((COUNTDOWN - 1)) -if [ $COUNTDOWN -lt 0 ]; then - COUNTDOWN=300 - /opt/homebrew/bin/node ~/Developer/raycast-scripts/layout_engine.js save silent > /dev/null 2>&1 - LAST_SAVED=$(date +"%H:%M:%S") -fi - -# Save the updated state -echo "{\"countdown\":$COUNTDOWN,\"lastSaved\":\"$LAST_SAVED\"}" > "$STATE_FILE" - -# Calculate minutes and seconds -MINUTES=$((COUNTDOWN / 60)) -SECONDS=$((COUNTDOWN % 60)) -DISPLAY_TIME=$(printf "%d:%02d" $MINUTES $SECONDS) - -# --- RAYCAST NATIVE MENU-BAR OUTPUT --- -# When mode is set to menu-bar, Raycast reads standard text output line-by-line -echo "$DISPLAY_TIME" -echo "---" -echo "๐Ÿ“… Last Saved: $LAST_SAVED" -echo "๐Ÿ“ธ Save Layout (โ‡งโŒ˜W) | bash='/opt/homebrew/bin/node $HOME/Developer/raycast-scripts/layout_engine.js save' terminal=false" -echo "๐Ÿ”„ Restore Layout (โ‡งโŒ˜R) | bash='/opt/homebrew/bin/node $HOME/Developer/raycast-scripts/layout_engine.js restore' terminal=false" -echo "๐Ÿš€ Rescue Windows (โ‡งโŒ˜โŒƒL) | bash='/opt/homebrew/bin/node $HOME/Developer/raycast-scripts/layout_engine.js rescue' terminal=false" diff --git a/layout_engine.js b/layout_engine.js deleted file mode 100755 index 14d24b8..0000000 --- a/layout_engine.js +++ /dev/null @@ -1,201 +0,0 @@ -const fs = require('fs'); -const path = require('path'); -const { execSync } = require('child_process'); - -const HOME = process.env.HOME; -const LAYOUT_FILE = path.join(HOME, '.hammerspoon/saved_layout.json'); -const CONFIG_FILE = path.join(HOME, '.hammerspoon/config.json'); -const TEMP_JS_FILE = '/tmp/raycast_window_engine.js'; - -let stubbornApps = ["Gemini", "AFFiNE", "Terminal", "System Settings"]; -let ignoreApps = ["TheBoringNotch", "Control Center", "Notification Center", "Dock", "BetterDisplay", "Stats", "DockDoor", "Bartender 6", "Bartender", "Arq", "Arq Agent", "TypeWhisper", "com.typewhisper.mac"]; - -if (fs.existsSync(CONFIG_FILE)) { - try { - const cfg = JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf8')); - if (cfg.stubbornAppsList) stubbornApps = Object.keys(cfg.stubbornAppsList); - if (cfg.ignoreListItems) ignoreApps = Object.keys(cfg.ignoreListItems); - } catch (e) {} -} - -const action = process.argv[2]; - -function getVisibleWindows() { - // Queries the global System Events window array directly, replicating hs.window.allWindows() - const captureScript = ` - var sys = Application('System Events'); - var out = []; - try { - var allWins = sys.windows(); - for (var i = 0; i < allWins.length; i++) { - var win = allWins[i]; - var proc = win.process(); - if (!proc) continue; - - var procName = proc.name(); - var bundleID = proc.bundleIdentifier() || ""; - var size = win.size(); - var pos = win.position(); - var title = win.title() || ""; - - if (size && size[0] > 10 && size[1] > 10 && pos && pos[0] !== undefined) { - out.push({ - appName: procName, - bundleID: bundleID, - winTitle: title, - x: Math.floor(pos[0]), - y: Math.floor(pos[1]), - w: Math.floor(size[0]), - h: Math.floor(size[1]) - }); - } - } - } catch(e) {} - JSON.stringify(out); - `; - - try { - fs.writeFileSync(TEMP_JS_FILE, captureScript, 'utf8'); - const rawOutput = execSync(`osascript -l JavaScript ${TEMP_JS_FILE}`).toString().trim(); - if (fs.existsSync(TEMP_JS_FILE)) fs.unlinkSync(TEMP_JS_FILE); - - if (!rawOutput || rawOutput === "[]") return []; - return JSON.parse(rawOutput); - } catch (e) { - if (fs.existsSync(TEMP_JS_FILE)) fs.unlinkSync(TEMP_JS_FILE); - return []; - } -} - -function saveLayout() { - const windows = getVisibleWindows().filter(w => w && !ignoreApps.includes(w.appName) && !ignoreApps.includes(w.bundleID)); - if (windows.length === 0) { - console.log("No active windows detected to save."); - return; - } - - const layout = { - saveTime: new Date().toLocaleTimeString(), - windows: windows - }; - - if (!fs.existsSync(path.dirname(LAYOUT_FILE))) { - fs.mkdirSync(path.dirname(LAYOUT_FILE), { recursive: true }); - } - - fs.writeFileSync(LAYOUT_FILE, JSON.stringify(layout, null, 2)); - console.log("Layout Saved Successfully"); -} - -function restoreLayout() { - if (!fs.existsSync(LAYOUT_FILE)) { - console.log("Restore failed: No saved layout found."); - return; - } - - const data = JSON.parse(fs.readFileSync(LAYOUT_FILE, 'utf8')); - if (!data.windows || data.windows.length === 0) return; - - const savedByApp = {}; - data.windows.forEach(win => { - if (ignoreApps.includes(win.appName) || ignoreApps.includes(win.bundleID)) return; - if (!savedByApp[win.appName]) savedByApp[win.appName] = []; - savedByApp[win.appName].push(win); - }); - - Object.keys(savedByApp).forEach(appName => { - savedByApp[appName].sort((a, b) => { - if (a.y === b.y) return a.x - b.x; - return a.y - b.y; - }); - }); - - let restoreScript = `var sys = Application('System Events');\n`; - Object.keys(savedByApp).forEach(appName => { - const savedEntries = savedByApp[appName]; - restoreScript += ` - try { - if (sys.processes.names().includes("${appName}")) { - var proc = sys.processes["${appName}"]; - var physicalWins = []; - var allWins = proc.windows(); - - for (var k = 0; k < allWins.length; k++) { - try { - var w = allWins[k]; - var s = w.size(); - if (s && s[0] > 10 && s[1] > 10) { - physicalWins.push(w); - } - } catch(err) {} - } - - physicalWins.sort(function(a, b) { - var posA = a.position(); var posB = b.position(); - if (!posA || !posB) return 0; - if (posA[1] === posB[1]) return posA[0] - posB[0]; - return posA[1] - posB[1]; - }); - - var savedEntriesForApp = ${JSON.stringify(savedEntries)}; - for (var i = 0; i < Math.min(savedEntriesForApp.length, physicalWins.length); i++) { - try { - var winData = savedEntriesForApp[i]; - var targetWin = physicalWins[i]; - - targetWin.position = [winData.x, winData.y]; - targetWin.size = [winData.w, winData.h]; - } catch(err) {} - } - } - } catch(e) {} - `; - }); - - try { - fs.writeFileSync(TEMP_JS_FILE, restoreScript, 'utf8'); - execSync(`osascript -l JavaScript ${TEMP_JS_FILE} 2>/dev/null`); - - if (data.windows.some(w => stubbornApps.includes(w.appName))) { - setTimeout(() => { - try { execSync(`osascript -l JavaScript ${TEMP_JS_FILE} 2>/dev/null`); } catch(e){} - if (fs.existsSync(TEMP_JS_FILE)) fs.unlinkSync(TEMP_JS_FILE); - }, 500); - } else { - if (fs.existsSync(TEMP_JS_FILE)) fs.unlinkSync(TEMP_JS_FILE); - } - } catch (e) {} - console.log("Layout Restored Successfully"); -} - -function rescueWindows() { - let rescueScript = ` - var sys = Application('System Events'); - var allWins = sys.windows(); - var stagger = 0; - for (var i = 0; i < allWins.length; i++) { - try { - var win = allWins[i]; - var proc = win.process(); - if (proc && proc.name() !== "Finder" && proc.name() !== "Dock") { - var s = win.size(); - if (s && s[0] > 10) { - win.position = [50 + stagger, 50 + stagger]; - stagger += 30; - if (stagger > 150) stagger = 0; - } - } - } catch(e) {} - } - `; - try { - fs.writeFileSync(TEMP_JS_FILE, rescueScript, 'utf8'); - execSync(`osascript -l JavaScript ${TEMP_JS_FILE} 2>/dev/null`); - } catch(e){} - if (fs.existsSync(TEMP_JS_FILE)) fs.unlinkSync(TEMP_JS_FILE); - console.log("Windows Cascaded to Laptop"); -} - -if (action === 'save') saveLayout(); -if (action === 'restore') restoreLayout(); -if (action === 'rescue') rescueWindows(); \ No newline at end of file diff --git a/load-layout.sh b/load-layout.sh deleted file mode 100755 index 11253cd..0000000 --- a/load-layout.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash - -# @raycast.schemaVersion 1 -# @raycast.title Load Window Layout -# @raycast.mode silent -# @raycast.icon ๐Ÿ–ฅ๏ธ -# @raycast.packageName Layout Selector - -# @raycast.argument1 { "type": "text", "placeholder": "Layout Name" } - -if [ ! -f /opt/homebrew/bin/hs ]; then - echo "Hammerspoon CLI link missing" - exit 1 -fi - -LAYOUT_NAME="$1" - -if [ -z "$LAYOUT_NAME" ]; then - exit 1 -fi - -/opt/homebrew/bin/hs -c "LayoutSelector.load('${LAYOUT_NAME}')" diff --git a/restore-layout.sh b/restore-layout.sh deleted file mode 100755 index 9d2e815..0000000 --- a/restore-layout.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -# @raycast.schemaVersion 1 -# @raycast.title Restore Layout -# @raycast.mode compact -# @raycast.packageName Window Management - -OUTPUT=$(/opt/homebrew/bin/node $HOME/Developer/raycast-scripts/layout_engine.js restore) -echo "$OUTPUT" \ No newline at end of file diff --git a/save-layout.sh b/save-layout.sh deleted file mode 100755 index 79e0b5f..0000000 --- a/save-layout.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash - -# @raycast.schemaVersion 1 -# @raycast.title Save Current Layout -# @raycast.mode silent -# @raycast.icon ๐Ÿ’พ -# @raycast.packageName Layout Selector - -# @raycast.argument1 { "type": "text", "placeholder": "Layout Name (e.g. Work)" } - -if [ ! -f /opt/homebrew/bin/hs ]; then - echo "Hammerspoon CLI link missing" - exit 1 -fi - -LAYOUT_NAME="$1" - -if [ -z "$LAYOUT_NAME" ]; then - exit 1 -fi - -/opt/homebrew/bin/hs -c "LayoutSelector.save('${LAYOUT_NAME}')" diff --git a/script-command.template.sh b/script-command.template.sh deleted file mode 100755 index b642b7e..0000000 --- a/script-command.template.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash - -# Raycast Script Command Template -# -# Duplicate this file and remove ".template." from the filename to get started. -# See full documentation here: https://github.com/raycast/script-commands -# -# Required parameters: -# @raycast.schemaVersion 1 -# @raycast.title My First Script -# @raycast.mode fullOutput -# -# Optional parameters: -# @raycast.icon ๐Ÿค– -# @raycast.packageName Raycast Scripts - -echo "Hello from My First Script" \ No newline at end of file diff --git a/select-layout-menu.sh b/select-layout-menu.sh deleted file mode 100755 index 2d8496d..0000000 --- a/select-layout-menu.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash - -# @raycast.schemaVersion 1 -# @raycast.title Select Layout Menu -# @raycast.mode silent -# @raycast.icon ๐Ÿ“‹ -# @raycast.packageName Layout Selector - -if [ ! -f /opt/homebrew/bin/hs ]; then - echo "Hammerspoon CLI link missing" - exit 1 -fi - -# Run the programmatic menu interface launcher -/opt/homebrew/bin/hs -c "LayoutSelector.showMenu()" diff --git a/trigger-monocle.sh b/trigger-monocle.sh deleted file mode 100755 index 09b1e15..0000000 --- a/trigger-monocle.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash - -# @raycast.schemaVersion 1 -# @raycast.title Trigger Monocle Window Layout -# @raycast.mode silent -# @raycast.icon ๐Ÿ–ฅ๏ธ -# @raycast.packageName Hammerspoon Core Automation - -# 1. Verify that the Hammerspoon command-line bridge is present -if [ ! -f /opt/homebrew/bin/hs ]; then - echo "Error: Hammerspoon CLI bridge not found at /opt/homebrew/bin/hs" - exit 1 -fi - -# 2. Send the execution string over to the headless background process -/opt/homebrew/bin/hs -c "hs.alert.show('Layout Synced via Raycast!', 2)" - -# Note: You can call any custom global functions defined inside your pulled Gitea scripts. -# To do that, replace the code string above with your specific Lua function name: -# /opt/homebrew/bin/hs -c "toggleMonocle()" diff --git a/workspace-status.sh b/workspace-status.sh new file mode 100755 index 0000000..9ea4854 --- /dev/null +++ b/workspace-status.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +# Required parameters: +# @raycast.schemaVersion 1 +# @raycast.title Workspace Auto-Save Status +# @raycast.mode inline +# @raycast.refreshTime 10s + +# Optional parameters: +# @raycast.icon ๐Ÿ’  +# @raycast.packageName Window Automation + +# 1. Pull active timer values from the live Hammerspoon engine state +COUNTDOWN=$(/opt/homebrew/bin/hs -c "print(WindowManager.saveCountdown)" 2>/dev/null) +LAST_SAVE=$(/opt/homebrew/bin/hs -c "print(WindowManager.lastSavedTime)" 2>/dev/null) + +# 2. Output structural string directly into the Raycast search results row +if [ -z "$COUNTDOWN" ] || [ "$COUNTDOWN" == "nil" ]; then + echo "Hammerspoon Offline" +else + MIN=$((COUNTDOWN / 60)) + SEC=$((COUNTDOWN % 60)) + printf "Next: %d:%02d | Saved: %s\n" $MIN $SEC "$LAST_SAVE" +fi \ No newline at end of file