@m13v/s4l 1.7.5-rc.2 → 1.7.5-rc.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/mcp/dist/index.js +571 -79
- package/mcp/dist/panel.html +2 -3
- package/mcp/dist/redditAuth.js +115 -0
- package/mcp/dist/runtime.js +83 -2
- package/mcp/dist/setup.js +142 -5
- package/mcp/dist/telemetry.js +13 -3
- package/mcp/dist/version.json +2 -2
- package/mcp/manifest.json +1 -1
- package/mcp/menubar/s4l_card.py +32 -6
- package/mcp/menubar/s4l_menubar.py +42 -111
- package/mcp/menubar/s4l_state.py +54 -187
- package/mcp/package.json +1 -1
- package/mcp/shared/onboarding-ledger.cjs +63 -4
- package/package.json +1 -1
- package/scripts/autopilot_stall_watch.py +3 -6
- package/scripts/browser_mutex.py +316 -0
- package/scripts/claude_job.py +21 -0
- package/scripts/config.py +118 -0
- package/scripts/counterparty_history.py +44 -6
- package/scripts/engage_github.py +7 -3
- package/scripts/engage_reddit.py +9 -3
- package/scripts/engagement_signal_feedback.py +256 -0
- package/scripts/learned_preferences.py +37 -14
- package/scripts/memory_snapshot.py +45 -0
- package/scripts/merge_review_queue.py +67 -3
- package/scripts/post_reddit.py +289 -24
- package/scripts/reddit_browser.py +62 -63
- package/scripts/reddit_browser_fetch.py +32 -0
- package/scripts/release-mcpb.sh +17 -0
- package/scripts/reset-test-machine.sh +13 -7
- package/scripts/scan_twitter_thread_followups.py +7 -1
- package/scripts/schedule_state.py +1 -1
- package/scripts/setup_reddit_auth.py +925 -0
- package/scripts/snapshot.py +96 -4
- package/scripts/stats.py +37 -13
- package/scripts/test_no_silent_fallbacks.py +281 -0
- package/scripts/trigger_promo_lane_test.sh +91 -0
- package/scripts/twitter_browser.py +183 -342
- package/scripts/twitter_scan.py +75 -10
- package/scripts/watchdog_hung_runs.py +15 -9
- package/skill/lib/harness-common.sh +344 -0
- package/skill/lib/linkedin-backend.sh +61 -161
- package/skill/lib/reddit-backend.sh +39 -125
- package/skill/lib/twitter-backend.sh +51 -273
- package/skill/lock.sh +57 -0
- package/skill/run-reddit-search-launchd.sh +4 -1
- package/skill/run-reddit-search.sh +51 -2
- package/skill/run-twitter-cycle.sh +44 -21
package/scripts/release-mcpb.sh
CHANGED
|
@@ -187,6 +187,23 @@ fi
|
|
|
187
187
|
|
|
188
188
|
command -v mcpb >/dev/null || die "mcpb CLI not found (npm i -g @anthropic-ai/mcpb)"
|
|
189
189
|
|
|
190
|
+
# ---- 0b. Regression gate: no silent-fallback / bare-python3 reintroductions --
|
|
191
|
+
# scripts/test_no_silent_fallbacks.py locks in two recurring bug classes that
|
|
192
|
+
# have separately shipped to customers more than once (X handle -> hardcoded
|
|
193
|
+
# "m13v_" impersonation, DEFAULT_ACCOUNTS, and bare "python3" subprocess spawns
|
|
194
|
+
# of Playwright-dependent scripts silently dying on a fresh install with no
|
|
195
|
+
# Playwright on PATH -- see bug_twitter_reply_bare_python3_no_playwright.md
|
|
196
|
+
# and bug_twitter_handle_scrape_brittle_m13v_fallback.md). Runs BEFORE any
|
|
197
|
+
# build/pack/publish work so a regression blocks the release, not a customer.
|
|
198
|
+
# Applies to every path that actually builds a new artifact (stable + both
|
|
199
|
+
# --staging and default runs); --promote ships an already-tested artifact
|
|
200
|
+
# byte-for-byte with no rebuild, so it's exempt (handled in step 0 above,
|
|
201
|
+
# which exits before reaching here) -- that artifact already passed this gate
|
|
202
|
+
# when it was first built.
|
|
203
|
+
say "Regression gate: scripts/test_no_silent_fallbacks.py"
|
|
204
|
+
python3 "$REPO_ROOT/scripts/test_no_silent_fallbacks.py" \
|
|
205
|
+
|| die "regression gate failed -- a silent-fallback / bare-python3 issue was (re)introduced. See output above; do not release until it's clean or the finding is reviewed into the test's ALLOWLIST with a reason."
|
|
206
|
+
|
|
190
207
|
# ---- 1. Resolve + WRITE version into the repo-root package.json -------------
|
|
191
208
|
# The repo-root package.json is the SINGLE source of truth: `npm pack` reads it
|
|
192
209
|
# to build the embedded pipeline.tgz, so the bundle shell and the bundled
|
|
@@ -304,12 +304,18 @@ fi
|
|
|
304
304
|
echo
|
|
305
305
|
|
|
306
306
|
# ---- 1c. Claude Desktop scheduled tasks -----------------------------------
|
|
307
|
-
# Onboarding creates the queue-worker
|
|
308
|
-
#
|
|
309
|
-
#
|
|
310
|
-
#
|
|
311
|
-
#
|
|
312
|
-
#
|
|
307
|
+
# Onboarding creates the queue-worker task (current installs: the universal
|
|
308
|
+
# `s4l-worker`; legacy installs: `saps-worker`/`saps-phase1-query`/
|
|
309
|
+
# `saps-phase2b-draft`/the deprecated single `social-autoposter-autopilot`)
|
|
310
|
+
# under ~/.claude/scheduled-tasks/. They live OUTSIDE the state dir, so a
|
|
311
|
+
# reset that skips them leaves idle workers firing every minute against a
|
|
312
|
+
# wiped install. TASK_IDS must be kept in sync with WORKER_TASK_IDS in
|
|
313
|
+
# s4l_menubar.py / schedule_state.py / scheduled_tasks_snapshot.py — this list
|
|
314
|
+
# went stale after the `s4l-worker` rename (2026-07-02) and every "deep reset"
|
|
315
|
+
# since then silently left the live task running (found 2026-07-15). Like the
|
|
316
|
+
# .mcpb registry, the host (Claude Desktop) owns the live schedule and
|
|
317
|
+
# rewrites it on quit. Step [0] already quit it; this warns only if it came
|
|
318
|
+
# back (--keep-claude / relaunch).
|
|
313
319
|
echo "[1c] Claude Desktop scheduled tasks (queue workers + deprecated autopilot)"
|
|
314
320
|
SCHED_DIR="$HOME_DIR/.claude/scheduled-tasks"
|
|
315
321
|
if pgrep -x "Claude" >/dev/null 2>&1; then
|
|
@@ -322,7 +328,7 @@ if [ -d "$SCHED_DIR" ]; then
|
|
|
322
328
|
[ -e "$d" ] && TASK_IDS+=("$(basename "$d")")
|
|
323
329
|
done
|
|
324
330
|
fi
|
|
325
|
-
for t in saps-phase1-query saps-phase2b-draft social-autoposter-autopilot; do
|
|
331
|
+
for t in s4l-worker saps-worker saps-phase1-query saps-phase2b-draft social-autoposter-autopilot; do
|
|
326
332
|
TASK_IDS+=("$t")
|
|
327
333
|
done
|
|
328
334
|
if [ "${#TASK_IDS[@]}" -gt 0 ]; then
|
|
@@ -65,6 +65,12 @@ DEFAULT_MAX_URLS = 40
|
|
|
65
65
|
REPO_DIR = os.path.expanduser("~/social-autoposter")
|
|
66
66
|
REPLY_PAGE_LIMIT = 500
|
|
67
67
|
|
|
68
|
+
# Pinned interpreter, never the literal "python3": twitter_browser.py (below)
|
|
69
|
+
# imports Playwright, and bare "python3" resolves to the caller's system
|
|
70
|
+
# Python on PATH, which has no Playwright on a fresh install (silent
|
|
71
|
+
# failure). See scripts/twitter_post_plan.py:131.
|
|
72
|
+
PYTHON = os.environ.get("S4L_PYTHON") or sys.executable
|
|
73
|
+
|
|
68
74
|
|
|
69
75
|
def load_config():
|
|
70
76
|
if os.path.exists(CONFIG_PATH):
|
|
@@ -137,7 +143,7 @@ def run_browser_scrape(urls, scroll_count=3):
|
|
|
137
143
|
f.write(u + "\n")
|
|
138
144
|
try:
|
|
139
145
|
proc = subprocess.run(
|
|
140
|
-
[
|
|
146
|
+
[PYTHON, os.path.join(REPO_DIR, "scripts/twitter_browser.py"),
|
|
141
147
|
"thread-followups", urls_path, str(scroll_count)],
|
|
142
148
|
capture_output=True, text=True, timeout=1800,
|
|
143
149
|
)
|
|
@@ -110,7 +110,7 @@ HEALTHY_DRAIN_MAX_SECONDS = 1200
|
|
|
110
110
|
# (an idle queue has no pending job at all, so a quiet pipeline never trips it).
|
|
111
111
|
STALL_SECONDS = HEALTHY_DRAIN_MAX_SECONDS
|
|
112
112
|
# A job claimed but still sitting in running/ this long: the worker picked it up
|
|
113
|
-
# and then wedged mid-run
|
|
113
|
+
# and then wedged mid-run.
|
|
114
114
|
RUNNING_STALL_SECONDS = HEALTHY_DRAIN_MAX_SECONDS
|
|
115
115
|
# The producer's "drafting Nm" label alive this long: the end-to-end clock. This
|
|
116
116
|
# is the only timer that spans claim→die→requeue churn loops, which reset the two
|