← back to Commercialrealestate
chore: macstudio3 migration — reconcile from mac2 + repoint paths (stevestudio2→macstudio3, node/npm/npx→/opt/homebrew)
883f96e858200c5f3467ceeca28bbb6cfb2715bf · 2026-07-03 08:07:55 -0700 · Steve
Files touched
M 5x/brokers-assert.jsM 5x/crcp-assert.jsM 5x/deals-assert.jsM 5x/index-assert.jsM 5x/map-assert.jsM 5x/rentrolls-assert.jsM 5x/sales-assert.jsM deploy/com.steve.cre-afternoon-report.plistM deploy/com.steve.cre-morning-report.plistM deploy/com.steve.cre-viewer.plistM deploy/com.steve.cre-weekly-refresh.plistM scripts/export-to-gsheet.jsM scripts/run-afternoon-report.shM scripts/run-morning-report.shM scripts/run-weekly-refresh.sh
Diff
commit 883f96e858200c5f3467ceeca28bbb6cfb2715bf
Author: Steve <steve@designerwallcoverings.com>
Date: Fri Jul 3 08:07:55 2026 -0700
chore: macstudio3 migration — reconcile from mac2 + repoint paths (stevestudio2→macstudio3, node/npm/npx→/opt/homebrew)
---
5x/brokers-assert.js | 2 +-
5x/crcp-assert.js | 2 +-
5x/deals-assert.js | 2 +-
5x/index-assert.js | 2 +-
5x/map-assert.js | 2 +-
5x/rentrolls-assert.js | 2 +-
5x/sales-assert.js | 2 +-
deploy/com.steve.cre-afternoon-report.plist | 2 +-
deploy/com.steve.cre-morning-report.plist | 2 +-
deploy/com.steve.cre-viewer.plist | 8 ++++----
deploy/com.steve.cre-weekly-refresh.plist | 2 +-
scripts/export-to-gsheet.js | 2 +-
scripts/run-afternoon-report.sh | 8 ++++----
scripts/run-morning-report.sh | 6 +++---
scripts/run-weekly-refresh.sh | 6 +++---
15 files changed, 25 insertions(+), 25 deletions(-)
diff --git a/5x/brokers-assert.js b/5x/brokers-assert.js
index d240805..80f8c82 100644
--- a/5x/brokers-assert.js
+++ b/5x/brokers-assert.js
@@ -3,7 +3,7 @@
// • #blist row click sets the firm search box (#firmq) + highlights graph [line 131]
// • showDetail(node) — the graph-node-click handler [line 76→78] — populates the detail pane
// • empty graph degrades with no crash/NaN
-const pw=require('/Users/stevestudio2/.claude/skills/browserbase/node_modules/playwright-core');
+const pw=require('/Users/macstudio3/.claude/skills/browserbase/node_modules/playwright-core');
const EXEC='/Applications/Google Chrome.app/Contents/MacOS/Google Chrome';
async function run(mockEmpty){
const errors=[]; const b=await pw.chromium.launch({executablePath:EXEC,headless:true});
diff --git a/5x/crcp-assert.js b/5x/crcp-assert.js
index 596f2df..2783dc2 100644
--- a/5x/crcp-assert.js
+++ b/5x/crcp-assert.js
@@ -1,6 +1,6 @@
// Strong crcp.html gate: tiles render with data (no NaN), 8 segment rows ATTACHED+correct, collapsed panel
// expands to visible, segment modal opens with a call-list, broker sort reorders, empty-data degrades clean.
-const pw=require('/Users/stevestudio2/.claude/skills/browserbase/node_modules/playwright-core');
+const pw=require('/Users/macstudio3/.claude/skills/browserbase/node_modules/playwright-core');
const EXEC='/Applications/Google Chrome.app/Contents/MacOS/Google Chrome';
async function run(mockEmpty){
const errors=[]; const b=await pw.chromium.launch({executablePath:EXEC,headless:true});
diff --git a/5x/deals-assert.js b/5x/deals-assert.js
index f8efca5..a5685da 100644
--- a/5x/deals-assert.js
+++ b/5x/deals-assert.js
@@ -1,6 +1,6 @@
// Strong deals.html gate (what /3x's --selector cannot do): assert the 6 charts actually drew DATA,
// no tile renders NaN/$NaN, and the EMPTY-DATA path degrades without crashing or showing NaN.
-const pw = require('/Users/stevestudio2/.claude/skills/browserbase/node_modules/playwright-core');
+const pw = require('/Users/macstudio3/.claude/skills/browserbase/node_modules/playwright-core');
const EXEC = '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome';
const CHARTS = ['cPipe','cType','cCap','cMed','cGeo','cBand'];
diff --git a/5x/index-assert.js b/5x/index-assert.js
index cd8c01b..179081f 100644
--- a/5x/index-assert.js
+++ b/5x/index-assert.js
@@ -3,7 +3,7 @@
// • changing #sort reorders the cards (first card changes)
// • clicking a filter .chip narrows the result set
// • empty data (mocked ranked.json/listings.json) degrades: 0 cards, no NaN, 0 swallowed JS errors
-const pw=require('/Users/stevestudio2/.claude/skills/browserbase/node_modules/playwright-core');
+const pw=require('/Users/macstudio3/.claude/skills/browserbase/node_modules/playwright-core');
const EXEC='/Applications/Google Chrome.app/Contents/MacOS/Google Chrome';
async function run(mockEmpty){
const errors=[]; const b=await pw.chromium.launch({executablePath:EXEC,headless:true});
diff --git a/5x/map-assert.js b/5x/map-assert.js
index 785813a..ff21a24 100644
--- a/5x/map-assert.js
+++ b/5x/map-assert.js
@@ -1,6 +1,6 @@
// Strong map.html gate (cluster-aware): markers drew per type, legend toggles add/remove layers, color-by Price
// recolors + shows the price key, popup aerial decodes (zoom in first to un-cluster), empty-data degrades.
-const pw=require('/Users/stevestudio2/.claude/skills/browserbase/node_modules/playwright-core');
+const pw=require('/Users/macstudio3/.claude/skills/browserbase/node_modules/playwright-core');
const EXEC='/Applications/Google Chrome.app/Contents/MacOS/Google Chrome';
async function run(label, mockEmpty){
const errors=[]; const b=await pw.chromium.launch({executablePath:EXEC,headless:true});
diff --git a/5x/rentrolls-assert.js b/5x/rentrolls-assert.js
index d40e097..b20a02c 100644
--- a/5x/rentrolls-assert.js
+++ b/5x/rentrolls-assert.js
@@ -1,6 +1,6 @@
// Strong rent-rolls.html gate: rolls render with unit table + NOI, DSCR calculator computes a real number,
// changing an input recomputes DSCR, no NaN; empty-data shows the empty state with no error.
-const pw=require('/Users/stevestudio2/.claude/skills/browserbase/node_modules/playwright-core');
+const pw=require('/Users/macstudio3/.claude/skills/browserbase/node_modules/playwright-core');
const EXEC='/Applications/Google Chrome.app/Contents/MacOS/Google Chrome';
async function run(mockEmpty){
const errors=[]; const b=await pw.chromium.launch({executablePath:EXEC,headless:true});
diff --git a/5x/sales-assert.js b/5x/sales-assert.js
index baef26c..b074b25 100644
--- a/5x/sales-assert.js
+++ b/5x/sales-assert.js
@@ -1,6 +1,6 @@
// Strong sales.html gate: table rows render with data (no NaN), both charts drew, a filter narrows rows,
// depth note present; empty-data degrades with no NaN/error.
-const pw=require('/Users/stevestudio2/.claude/skills/browserbase/node_modules/playwright-core');
+const pw=require('/Users/macstudio3/.claude/skills/browserbase/node_modules/playwright-core');
const EXEC='/Applications/Google Chrome.app/Contents/MacOS/Google Chrome';
async function run(mockEmpty){
const errors=[]; const b=await pw.chromium.launch({executablePath:EXEC,headless:true});
diff --git a/deploy/com.steve.cre-afternoon-report.plist b/deploy/com.steve.cre-afternoon-report.plist
index f174362..e968412 100644
--- a/deploy/com.steve.cre-afternoon-report.plist
+++ b/deploy/com.steve.cre-afternoon-report.plist
@@ -7,7 +7,7 @@
<key>ProgramArguments</key>
<array>
<string>/bin/zsh</string>
- <string>/Users/stevestudio2/Projects/commercialrealestate/scripts/run-afternoon-report.sh</string>
+ <string>/Users/macstudio3/Projects/commercialrealestate/scripts/run-afternoon-report.sh</string>
</array>
<key>StartCalendarInterval</key>
<dict>
diff --git a/deploy/com.steve.cre-morning-report.plist b/deploy/com.steve.cre-morning-report.plist
index 87acdb3..84627b7 100644
--- a/deploy/com.steve.cre-morning-report.plist
+++ b/deploy/com.steve.cre-morning-report.plist
@@ -7,7 +7,7 @@
<key>ProgramArguments</key>
<array>
<string>/bin/zsh</string>
- <string>/Users/stevestudio2/Projects/commercialrealestate/scripts/run-morning-report.sh</string>
+ <string>/Users/macstudio3/Projects/commercialrealestate/scripts/run-morning-report.sh</string>
</array>
<key>StartCalendarInterval</key>
<dict>
diff --git a/deploy/com.steve.cre-viewer.plist b/deploy/com.steve.cre-viewer.plist
index a7f1d39..09cc246 100644
--- a/deploy/com.steve.cre-viewer.plist
+++ b/deploy/com.steve.cre-viewer.plist
@@ -7,12 +7,12 @@
<key>ProgramArguments</key>
<array>
- <string>/usr/local/bin/node</string>
+ <string>/opt/homebrew/bin/node</string>
<string>scripts/serve.js</string>
</array>
<key>WorkingDirectory</key>
- <string>/Users/stevestudio2/Projects/commercialrealestate</string>
+ <string>/Users/macstudio3/Projects/commercialrealestate</string>
<key>EnvironmentVariables</key>
<dict>
@@ -29,8 +29,8 @@
<true/>
<key>StandardOutPath</key>
- <string>/Users/stevestudio2/Projects/commercialrealestate/tmp/cre-viewer.launchd.log</string>
+ <string>/Users/macstudio3/Projects/commercialrealestate/tmp/cre-viewer.launchd.log</string>
<key>StandardErrorPath</key>
- <string>/Users/stevestudio2/Projects/commercialrealestate/tmp/cre-viewer.launchd.err.log</string>
+ <string>/Users/macstudio3/Projects/commercialrealestate/tmp/cre-viewer.launchd.err.log</string>
</dict>
</plist>
diff --git a/deploy/com.steve.cre-weekly-refresh.plist b/deploy/com.steve.cre-weekly-refresh.plist
index 0f1cf33..c31aad4 100644
--- a/deploy/com.steve.cre-weekly-refresh.plist
+++ b/deploy/com.steve.cre-weekly-refresh.plist
@@ -7,7 +7,7 @@
<key>ProgramArguments</key>
<array>
<string>/bin/zsh</string>
- <string>/Users/stevestudio2/Projects/commercialrealestate/scripts/run-weekly-refresh.sh</string>
+ <string>/Users/macstudio3/Projects/commercialrealestate/scripts/run-weekly-refresh.sh</string>
</array>
<key>StartCalendarInterval</key>
<dict>
diff --git a/scripts/export-to-gsheet.js b/scripts/export-to-gsheet.js
index 1f2998a..af0e836 100644
--- a/scripts/export-to-gsheet.js
+++ b/scripts/export-to-gsheet.js
@@ -7,7 +7,7 @@
const fs = require('fs'), crypto = require('crypto'), https = require('https'), path = require('path');
const { Pool } = require('pg');
const ROOT = path.join(__dirname, '..');
-const SA = JSON.parse(fs.readFileSync('/Users/stevestudio2/Projects/secrets-manager/gmc-sa-146735262.json', 'utf8'));
+const SA = JSON.parse(fs.readFileSync('/Users/macstudio3/Projects/secrets-manager/gmc-sa-146735262.json', 'utf8'));
const SHARE_WITH = 'steve@designerwallcoverings.com';
const pool = new Pool({ host: '/tmp', port: 5432, database: 'cre', user: process.env.USER || 'stevestudio2' });
diff --git a/scripts/run-afternoon-report.sh b/scripts/run-afternoon-report.sh
index c861a27..2934c26 100755
--- a/scripts/run-afternoon-report.sh
+++ b/scripts/run-afternoon-report.sh
@@ -15,7 +15,7 @@ LOG=/tmp/cre-afternoon-report.log
echo "===== afternoon run $(date) =====" >> "$LOG"
# 1) Snapshot listing ids BEFORE the scrape so the report can diff "what's new since morning".
-/usr/local/bin/node -e '
+/opt/homebrew/bin/node -e '
const fs=require("fs");
const d=JSON.parse(fs.readFileSync("data/listings.json","utf8"));
fs.writeFileSync("data/.pre-afternoon-ids.json", JSON.stringify({ at:new Date().toISOString(), ids:d.listings.map(l=>l.id) }));
@@ -24,13 +24,13 @@ echo "===== afternoon run $(date) =====" >> "$LOG"
# 2) Re-scrape Crexi (appends new in-band SFV listings, deduped). Non-fatal: if Browserbase is down we still
# re-rank + report the red-hot deals on existing data.
-/usr/local/bin/node scripts/refresh-listings.js >> "$LOG" 2>&1 || echo "refresh-listings failed (continuing)" >> "$LOG"
+/opt/homebrew/bin/node scripts/refresh-listings.js >> "$LOG" 2>&1 || echo "refresh-listings failed (continuing)" >> "$LOG"
# 3) Re-rank (local Qwen, cached -> fresh only for genuinely new listings).
-/usr/local/bin/node scripts/analyze.js >> "$LOG" 2>&1
+/opt/homebrew/bin/node scripts/analyze.js >> "$LOG" 2>&1
# 4) Build the afternoon report HTML and email it to both recipients (self-contained send).
-/usr/local/bin/node scripts/afternoon-report.js >> "$LOG" 2>&1
+/opt/homebrew/bin/node scripts/afternoon-report.js >> "$LOG" 2>&1
# 5) Commit the day's data + report.
git -c user.email=steve@designerwallcoverings.com -c user.name="Steve" add -A >> "$LOG" 2>&1
diff --git a/scripts/run-morning-report.sh b/scripts/run-morning-report.sh
index d46512f..bfb015c 100755
--- a/scripts/run-morning-report.sh
+++ b/scripts/run-morning-report.sh
@@ -7,11 +7,11 @@ cd "$HOME/Projects/commercialrealestate" || exit 1
LOG=/tmp/cre-morning-report.log
echo "===== run $(date) =====" >> "$LOG"
-/usr/local/bin/node scripts/analyze.js >> "$LOG" 2>&1
-REPORT_DATE="$(date +%Y-%m-%d)" /usr/local/bin/node scripts/morning-report.js > data/morning-report.html 2>> "$LOG"
+/opt/homebrew/bin/node scripts/analyze.js >> "$LOG" 2>&1
+REPORT_DATE="$(date +%Y-%m-%d)" /opt/homebrew/bin/node scripts/morning-report.js > data/morning-report.html 2>> "$LOG"
TODAY="$(date +%Y-%m-%d)"
-PROMPT="Read /Users/stevestudio2/Projects/commercialrealestate/data/morning-report.html and send its FULL contents as the HTML body of an email using the mcp__george__gmail_send tool with account 'steve-office' to 'steve@designerwallcoverings.com, steveabramsdesigns@gmail.com'. Subject: 'SFV CRE - Top 10 Opportunities ($TODAY)'. Send the HTML exactly as-is; do not summarize, truncate, or modify it. Sending that one email is the ONLY action to take."
+PROMPT="Read /Users/macstudio3/Projects/commercialrealestate/data/morning-report.html and send its FULL contents as the HTML body of an email using the mcp__george__gmail_send tool with account 'steve-office' to 'steve@designerwallcoverings.com, steveabramsdesigns@gmail.com'. Subject: 'SFV CRE - Top 10 Opportunities ($TODAY)'. Send the HTML exactly as-is; do not summarize, truncate, or modify it. Sending that one email is the ONLY action to take."
"$HOME/.npm-global/bin/claude" -p "$PROMPT" \
--allowedTools "Read" "mcp__george__gmail_send" \
diff --git a/scripts/run-weekly-refresh.sh b/scripts/run-weekly-refresh.sh
index d08991a..d63b568 100755
--- a/scripts/run-weekly-refresh.sh
+++ b/scripts/run-weekly-refresh.sh
@@ -7,13 +7,13 @@ cd "$HOME/Projects/commercialrealestate" || exit 1
LOG=/tmp/cre-weekly-refresh.log
echo "===== refresh $(date) =====" >> "$LOG"
-/usr/local/bin/node scripts/refresh-listings.js >> "$LOG" 2>&1
-/usr/local/bin/node scripts/analyze.js >> "$LOG" 2>&1
+/opt/homebrew/bin/node scripts/refresh-listings.js >> "$LOG" 2>&1
+/opt/homebrew/bin/node scripts/analyze.js >> "$LOG" 2>&1
git -c user.email=steve@designerwallcoverings.com -c user.name="Steve" add -A >> "$LOG" 2>&1
git -c user.email=steve@designerwallcoverings.com -c user.name="Steve" commit -q -m "weekly Crexi refresh $(date +%Y-%m-%d)" >> "$LOG" 2>&1
-ADDED=$(/usr/local/bin/node -e 'try{process.stdout.write(String(require("./data/last-refresh.json").added))}catch(e){process.stdout.write("0")}')
+ADDED=$(/opt/homebrew/bin/node -e 'try{process.stdout.write(String(require("./data/last-refresh.json").added))}catch(e){process.stdout.write("0")}')
echo "added=$ADDED" >> "$LOG"
if [ "$ADDED" -gt 0 ] 2>/dev/null; then
"$HOME/.npm-global/bin/claude" -p "Send a short plain-text email via mcp__george__gmail_send account 'steve-office' to steve@designerwallcoverings.com. Subject: 'SFV CRE weekly refresh: $ADDED new listings'. Body: 'The weekly Crexi refresh added $ADDED new in-band active SFV listing(s) to the ranker; they are now in the daily Top-10 at http://127.0.0.1:9911. Auto-added listings carry broker/unverified caps - verify before acting.' Send only that one email." \
← 253a437 auto-save: 2026-07-02T17:51:29 (1 files) — public/broker-gri
·
back to Commercialrealestate
·
condos: Amazon-rail UI live + /api/condos snapshot fallback a665e5c →