@m13v/s4l 1.7.1-rc.2 → 1.7.1-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/bin/cli.js +23 -0
- package/mcp/dist/index.js +332 -24
- package/mcp/dist/onboarding.js +3 -10
- package/mcp/dist/panel.html +42 -31
- package/mcp/dist/product-link.html +1 -1
- package/mcp/dist/runtime.js +101 -1
- package/mcp/dist/telemetry.js +80 -3
- package/mcp/dist/version.json +2 -2
- package/mcp/manifest.json +9 -1
- package/mcp/menubar/dashboard_server.py +12 -0
- package/mcp/menubar/s4l_card.py +472 -96
- package/mcp/menubar/s4l_menubar.py +269 -26
- package/mcp/menubar/s4l_state.py +169 -23
- package/mcp/package.json +1 -1
- package/mcp/shared/doctor.cjs +8 -0
- package/mcp/shared/onboarding-ledger.cjs +1 -0
- package/package.json +3 -1
- package/scripts/active_users.py +3 -6
- package/scripts/autopilot_stall_watch.py +200 -16
- package/scripts/claude_job.py +6 -0
- package/scripts/feedback_digest.py +34 -6
- package/scripts/get-latest-staging-mcpb.sh +50 -0
- package/scripts/harness_overlay.py +45 -0
- package/scripts/identity.py +26 -0
- package/scripts/learned_preferences.py +241 -32
- package/scripts/link_tail.py +167 -91
- package/scripts/mark_event.py +128 -0
- package/scripts/memory_snapshot.py +62 -0
- package/scripts/pick_twitter_thread_target.py +1 -1
- package/scripts/release-mcpb.sh +48 -0
- package/scripts/reset-test-machine.sh +85 -3
- package/scripts/s4l_mode.py +7 -5
- package/scripts/scheduled_tasks_snapshot.py +107 -0
- package/scripts/send_gmail_report.py +76 -0
- package/scripts/sentry_digest.py +81 -189
- package/scripts/sentry_init.py +43 -15
- package/scripts/setup_twitter_auth.py +76 -38
- package/scripts/snapshot.py +20 -0
- package/scripts/twitter_post_plan.py +39 -13
- package/skill/dm-outreach-twitter.sh +19 -0
- package/skill/engage-twitter.sh +27 -0
- package/skill/run-draft-and-publish.sh +13 -12
- package/skill/run-linkedin.sh +9 -1
- package/skill/run-twitter-cycle.sh +199 -27
- package/skill/sentry-digest.sh +125 -12
package/skill/sentry-digest.sh
CHANGED
|
@@ -1,19 +1,132 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
# sentry-digest.sh — critical (level:error/fatal) Sentry issue digest for the
|
|
3
|
-
# s4l Sentry project. Replaces the raw per-issue Sentry alert email
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
#
|
|
3
|
+
# s4l Sentry project. Replaces the raw per-issue Sentry alert email.
|
|
4
|
+
#
|
|
5
|
+
# Two-step design (mirrors ~/fazm/inbox/skill/check-query-insights.sh):
|
|
6
|
+
# 1. scripts/sentry_digest.py pulls issues + diffs against the ledger
|
|
7
|
+
# (mechanical, no LLM). If nothing is NEW or GROWING, exit here, no
|
|
8
|
+
# Claude spawn, no email, no ledger write (ledger is only ever written
|
|
9
|
+
# by the investigating Claude session, see SENTRY-DIGEST-SKILL.md).
|
|
10
|
+
# 2. If something changed, spawn Claude to actually investigate (read the
|
|
11
|
+
# crashing code, check git log, judge actionability) and send ONE
|
|
12
|
+
# human-readable email, not a raw data dump.
|
|
13
|
+
#
|
|
14
|
+
# Wired by launchd/com.m13v.s4l-sentry-digest.plist (every 4 hours).
|
|
7
15
|
|
|
8
|
-
|
|
16
|
+
set -euo pipefail
|
|
17
|
+
|
|
18
|
+
# claude (claude-account-rotator wrapper) and gtimeout must be resolvable
|
|
19
|
+
# regardless of how this script is invoked; launchd's plist PATH covers this,
|
|
20
|
+
# but keep it explicit so a manual run also works.
|
|
21
|
+
export PATH="$HOME/.nvm/versions/node/v20.19.4/bin:/opt/homebrew/bin:/usr/local/bin:$HOME/claude-account-rotator/bin:$PATH"
|
|
22
|
+
|
|
23
|
+
source "$(dirname "$0")/lock.sh"
|
|
24
|
+
acquire_lock "sentry-digest" 1800
|
|
25
|
+
|
|
26
|
+
REPO_DIR="$HOME/social-autoposter"
|
|
27
|
+
SCRIPTS_DIR="$REPO_DIR/scripts"
|
|
9
28
|
LOG_DIR="$REPO_DIR/skill/logs"
|
|
29
|
+
LEDGER_PATH="$REPO_DIR/scripts/state/sentry_digest_ledger.json"
|
|
30
|
+
CLAUDE_BIN="${CLAUDE_BIN:-$HOME/claude-account-rotator/bin/claude}"
|
|
31
|
+
PYTHON_BIN="${PYTHON_BIN:-/opt/homebrew/bin/python3.11}"
|
|
32
|
+
[ -x "$PYTHON_BIN" ] || PYTHON_BIN="/usr/bin/python3"
|
|
10
33
|
mkdir -p "$LOG_DIR"
|
|
11
|
-
LOG_FILE="$LOG_DIR/sentry-digest-$(date +%Y%m%d).log"
|
|
12
34
|
|
|
13
|
-
|
|
35
|
+
TS=$(date +%Y-%m-%d_%H%M%S)
|
|
36
|
+
LOG_FILE="$LOG_DIR/sentry-digest-$TS.log"
|
|
37
|
+
SCAN_FILE="$LOG_DIR/sentry-digest-scan-$TS.json"
|
|
38
|
+
OUTCOME_FILE="$LOG_DIR/outcome-sentry-digest-$TS.json"
|
|
39
|
+
|
|
40
|
+
log() { echo "[$(date +%H:%M:%S)] $*" | tee -a "$LOG_FILE"; }
|
|
41
|
+
|
|
42
|
+
cd "$REPO_DIR"
|
|
43
|
+
|
|
44
|
+
log "=== Sentry digest scan: $(date) ==="
|
|
45
|
+
"$PYTHON_BIN" "$SCRIPTS_DIR/sentry_digest.py" --out "$SCAN_FILE" 2>&1 | tee -a "$LOG_FILE"
|
|
46
|
+
SCAN_EXIT=${PIPESTATUS[0]}
|
|
47
|
+
if [ "$SCAN_EXIT" -ne 0 ]; then
|
|
48
|
+
log "ERROR: sentry_digest.py scan failed (exit $SCAN_EXIT)"
|
|
49
|
+
exit 1
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
FIRST_RUN=$("$PYTHON_BIN" -c "import json; print(json.load(open('$SCAN_FILE'))['firstRun'])")
|
|
53
|
+
NEW_COUNT=$("$PYTHON_BIN" -c "import json; print(json.load(open('$SCAN_FILE'))['newCount'])")
|
|
54
|
+
GROWING_COUNT=$("$PYTHON_BIN" -c "import json; print(json.load(open('$SCAN_FILE'))['growingCount'])")
|
|
55
|
+
|
|
56
|
+
if [ "$FIRST_RUN" = "False" ] && [ "$NEW_COUNT" -eq 0 ] && [ "$GROWING_COUNT" -eq 0 ]; then
|
|
57
|
+
log "Nothing new or growing. Skipping Claude spawn and email."
|
|
58
|
+
find "$LOG_DIR" -name "sentry-digest-scan-*.json" -mtime +7 -delete 2>/dev/null || true
|
|
59
|
+
find "$LOG_DIR" -name "sentry-digest-*.log" -mtime +30 -delete 2>/dev/null || true
|
|
60
|
+
exit 0
|
|
61
|
+
fi
|
|
62
|
+
|
|
63
|
+
# Step 2: spawn Claude to investigate and email
|
|
64
|
+
PROMPT_FILE=$(mktemp)
|
|
65
|
+
cat > "$PROMPT_FILE" <<PROMPT_EOF
|
|
66
|
+
Read ~/social-autoposter/skill/SENTRY-DIGEST-SKILL.md for the full workflow.
|
|
67
|
+
|
|
68
|
+
## Run metadata
|
|
69
|
+
|
|
70
|
+
- First run (ledger was empty): $FIRST_RUN
|
|
71
|
+
- New issues this scan: $NEW_COUNT
|
|
72
|
+
- Growing issues this scan: $GROWING_COUNT
|
|
73
|
+
- Sentry auth token: read it yourself with
|
|
74
|
+
security find-generic-password -s sentry-auth-token -w
|
|
75
|
+
|
|
76
|
+
## Scan result (from sentry_digest.py)
|
|
77
|
+
|
|
78
|
+
Full result is on disk at:
|
|
79
|
+
$SCAN_FILE
|
|
80
|
+
|
|
81
|
+
## Ledger path
|
|
82
|
+
|
|
83
|
+
$LEDGER_PATH
|
|
84
|
+
|
|
85
|
+
## Outcome file
|
|
86
|
+
|
|
87
|
+
Write your JSON outcome to:
|
|
88
|
+
$OUTCOME_FILE
|
|
89
|
+
|
|
90
|
+
Now run the workflow.
|
|
91
|
+
PROMPT_EOF
|
|
92
|
+
|
|
93
|
+
log "Spawning Claude Code session for investigation..."
|
|
94
|
+
log " Scan file: $SCAN_FILE"
|
|
95
|
+
log " Outcome file: $OUTCOME_FILE"
|
|
96
|
+
|
|
97
|
+
CLAUDE_EXIT=0
|
|
98
|
+
gtimeout 1800 "$CLAUDE_BIN" \
|
|
99
|
+
-p "$(cat "$PROMPT_FILE")" \
|
|
100
|
+
--dangerously-skip-permissions \
|
|
101
|
+
2>&1 | tee -a "$LOG_FILE" || CLAUDE_EXIT=$?
|
|
102
|
+
|
|
103
|
+
rm -f "$PROMPT_FILE"
|
|
104
|
+
|
|
105
|
+
if [ $CLAUDE_EXIT -eq 124 ]; then
|
|
106
|
+
log "ERROR: Claude Code timed out after 30 minutes"
|
|
107
|
+
elif [ $CLAUDE_EXIT -ne 0 ]; then
|
|
108
|
+
log "WARNING: Claude Code exited with code $CLAUDE_EXIT"
|
|
109
|
+
fi
|
|
110
|
+
|
|
111
|
+
log "--- Post-run validation ---"
|
|
112
|
+
if [ -f "$OUTCOME_FILE" ]; then
|
|
113
|
+
log "Outcome file found:"
|
|
114
|
+
cat "$OUTCOME_FILE" >> "$LOG_FILE"
|
|
115
|
+
REPORT_SENT=$("$PYTHON_BIN" -c "import json; d=json.load(open('$OUTCOME_FILE')); print(d.get('reportEmailSent', False))" 2>/dev/null || echo "False")
|
|
116
|
+
LEDGER_WRITTEN=$("$PYTHON_BIN" -c "import json; d=json.load(open('$OUTCOME_FILE')); print(d.get('ledgerWritten', False))" 2>/dev/null || echo "False")
|
|
117
|
+
SUMMARY=$("$PYTHON_BIN" -c "import json; d=json.load(open('$OUTCOME_FILE')); print(d.get('summary', 'No summary'))" 2>/dev/null || echo "No summary")
|
|
118
|
+
log " reportEmailSent: $REPORT_SENT"
|
|
119
|
+
log " ledgerWritten: $LEDGER_WRITTEN"
|
|
120
|
+
log " summary: $SUMMARY"
|
|
121
|
+
if [ "$LEDGER_WRITTEN" != "True" ]; then
|
|
122
|
+
log "WARNING: agent did not confirm writing the ledger; next run may re-flag the same issues"
|
|
123
|
+
fi
|
|
124
|
+
else
|
|
125
|
+
log "WARNING: No outcome file produced. Agent may not have completed the workflow."
|
|
126
|
+
fi
|
|
127
|
+
|
|
128
|
+
log "=== Done Sentry digest run (claude_exit=$CLAUDE_EXIT) ==="
|
|
14
129
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
echo
|
|
19
|
-
} >> "$LOG_FILE" 2>&1
|
|
130
|
+
find "$LOG_DIR" -name "sentry-digest-*.log" -mtime +30 -delete 2>/dev/null || true
|
|
131
|
+
find "$LOG_DIR" -name "sentry-digest-scan-*.json" -mtime +7 -delete 2>/dev/null || true
|
|
132
|
+
find "$LOG_DIR" -name "outcome-sentry-digest-*.json" -mtime +30 -delete 2>/dev/null || true
|