@m13v/s4l 1.7.2-rc.2 → 1.7.2-rc.4
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/version.json
CHANGED
package/mcp/manifest.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"dxt_version": "0.1",
|
|
3
3
|
"name": "social-autoposter",
|
|
4
4
|
"display_name": "S4L",
|
|
5
|
-
"version": "1.7.2-rc.
|
|
5
|
+
"version": "1.7.2-rc.4",
|
|
6
6
|
"description": "Draft, review, approve, and autopilot X/Twitter posts.",
|
|
7
7
|
"long_description": "## **⚠️ The disclaimer above is generic Claude boilerplate.** Anthropic shows the same warning on every plugin regardless of what it does; any plugin has the same level of access as any app you download from the internet.\n\nS4L is an open source product developed by Mediar.ai Incorporated, a VC-backed San Francisco-based startup.\n\nTo get started:\n\n1\\. Copy this prompt: **Set me up on S4L plugin end to end**\n\n2\\. Quit with CMD+Q, reopen Claude, paste into a new chat.\n\nWhat happens next:\n\n* About every 5 minutes S4L scans X for posts that match your topics and drafts replies in your voice.\n* Drafts show up as review cards, usually the first within a few minutes. Nothing is posted automatically; you approve each one.\n* Posting autopilot stays off until you explicitly turn it on.",
|
|
8
8
|
"author": {
|
|
@@ -785,19 +785,12 @@ class S4LMenuBar(rumps.App):
|
|
|
785
785
|
relaunch. Primary action for this case now instead of re-arm: no
|
|
786
786
|
clipboard paste, no chat turn required. Re-arm remains the fallback
|
|
787
787
|
for the rarer case where no session directory exists yet for the
|
|
788
|
-
active account (see _build_menu) — fix 5 never fabricates one.
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
"schedule for this account. Its window will close and reopen "
|
|
795
|
-
"in a moment — drafting starts within a few minutes after."
|
|
796
|
-
),
|
|
797
|
-
ok="Restart & Finish Setup", cancel="Cancel",
|
|
798
|
-
)
|
|
799
|
-
if choice != 1:
|
|
800
|
-
return
|
|
788
|
+
active account (see _build_menu) — fix 5 never fabricates one.
|
|
789
|
+
|
|
790
|
+
No confirm dialog: the restart is already disclosed in the menu item
|
|
791
|
+
label itself ("...(restarts Claude)", _build_menu) — a modal repeating
|
|
792
|
+
that would just be a second click for information the user already
|
|
793
|
+
has (2026-07-09). The notify toast below still tells them it started."""
|
|
801
794
|
_capture_msg(
|
|
802
795
|
"S4L finish-schedule-setup clicked",
|
|
803
796
|
phase="draft_schedule",
|
|
@@ -1147,7 +1140,7 @@ class S4LMenuBar(rumps.App):
|
|
|
1147
1140
|
"Uninstall: keep your X login + browser layer (quick uninstall).\n"
|
|
1148
1141
|
"Deep wipe: also remove the shared browser profiles + toolchain."
|
|
1149
1142
|
),
|
|
1150
|
-
ok="Uninstall & Restart Claude", cancel="Cancel", other="Deep wipe",
|
|
1143
|
+
ok="Uninstall & Restart Claude", cancel="Cancel", other="Deep wipe & Restart Claude",
|
|
1151
1144
|
)
|
|
1152
1145
|
if choice == 0: # cancel
|
|
1153
1146
|
return
|
|
@@ -3008,7 +3001,6 @@ class S4LMenuBar(rumps.App):
|
|
|
3008
3001
|
items.append(rumps.MenuItem("Resume S4L", callback=self._pause_toggle))
|
|
3009
3002
|
else:
|
|
3010
3003
|
items.append(rumps.MenuItem("Pause S4L", callback=self._pause_toggle))
|
|
3011
|
-
items.append(self._label(" stop drafting/posting, keep Claude + tray running"))
|
|
3012
3004
|
items.append(rumps.separator)
|
|
3013
3005
|
|
|
3014
3006
|
# Attention = the draft schedule isn't running for THIS account (missing or
|
|
@@ -3112,19 +3104,15 @@ class S4LMenuBar(rumps.App):
|
|
|
3112
3104
|
personal_on = bool(flags.get("personal_brand"))
|
|
3113
3105
|
promo_on = bool(flags.get("promotion"))
|
|
3114
3106
|
items.append(rumps.separator)
|
|
3115
|
-
items.append(self._label("Engagement lanes"))
|
|
3116
3107
|
pb_item = rumps.MenuItem("Personal brand", callback=self._toggle_personal)
|
|
3117
3108
|
pb_item.state = 1 if personal_on else 0
|
|
3118
3109
|
items.append(pb_item)
|
|
3119
|
-
items.append(self._label(" organic, link-free engagement"))
|
|
3120
3110
|
pr_item = rumps.MenuItem("Product promotion", callback=self._toggle_promotion)
|
|
3121
3111
|
pr_item.state = 1 if promo_on else 0
|
|
3122
3112
|
items.append(pr_item)
|
|
3123
|
-
items.append(self._label(" promoting your products (link replies)"))
|
|
3124
3113
|
if personal_on and promo_on:
|
|
3125
3114
|
# Both lanes on: the split becomes meaningful, so offer the presets.
|
|
3126
3115
|
share = st.read_split()
|
|
3127
|
-
items.append(self._label(f" both on · cycles split {self._split_pct(share)}"))
|
|
3128
3116
|
split_menu = rumps.MenuItem(f"Lane split: {self._split_pct(share)}")
|
|
3129
3117
|
for preset in self.SPLIT_PRESETS:
|
|
3130
3118
|
it = rumps.MenuItem(
|
|
@@ -3141,7 +3129,6 @@ class S4LMenuBar(rumps.App):
|
|
|
3141
3129
|
# carries a Feedback button); named for what it does to the pipeline,
|
|
3142
3130
|
# not the mechanism.
|
|
3143
3131
|
items.append(rumps.MenuItem("Give overall feedback to AI…", callback=self._menu_feedback))
|
|
3144
|
-
items.append(self._label(" overall guidance, steers future drafts"))
|
|
3145
3132
|
# While the update-verify marker is pending, the pipeline copy still
|
|
3146
3133
|
# resolves the OLD version (it only advances once the restarted server
|
|
3147
3134
|
# re-provisions repo/package, ~2 min), so the snapshot honestly reports
|
|
@@ -3168,8 +3155,10 @@ class S4LMenuBar(rumps.App):
|
|
|
3168
3155
|
items.append(rumps.separator)
|
|
3169
3156
|
items.append(rumps.MenuItem("Tidy autopilot history…", callback=self._prompt_relocate_tasks))
|
|
3170
3157
|
items.append(rumps.separator)
|
|
3171
|
-
|
|
3172
|
-
|
|
3158
|
+
quit_menu = rumps.MenuItem("Quit or Uninstall")
|
|
3159
|
+
quit_menu.add(rumps.MenuItem("Uninstall S4L…", callback=self._reset_machine))
|
|
3160
|
+
quit_menu.add(rumps.MenuItem("Quit", callback=self._quit_app))
|
|
3161
|
+
items.append(quit_menu)
|
|
3173
3162
|
|
|
3174
3163
|
# Collapse consecutive/edge separators so an empty section (e.g. State C
|
|
3175
3164
|
# now renders no status labels) can't leave a doubled or dangling divider.
|
package/mcp/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@m13v/s4l-mcp",
|
|
3
|
-
"version": "1.7.2-rc.
|
|
3
|
+
"version": "1.7.2-rc.4",
|
|
4
4
|
"private": true,
|
|
5
5
|
"description": "Desktop MCP client for social-autoposter (X/Twitter rail): manual draft/review/approve loop, autopilot control, and stats. Thin wrapper over the existing pipeline scripts.",
|
|
6
6
|
"license": "MIT",
|
package/package.json
CHANGED
|
@@ -60,14 +60,26 @@ except Exception: # standalone fallbacks
|
|
|
60
60
|
|
|
61
61
|
|
|
62
62
|
def _is_prep_result(obj):
|
|
63
|
-
"""True iff obj looks like a twitter-prep result (candidates
|
|
63
|
+
"""True iff obj looks like a twitter-prep result (drafted candidates).
|
|
64
|
+
|
|
65
|
+
"reply_text" was the single-draft field before the 2026-07-07/08 two-draft
|
|
66
|
+
redesign (draft_a_text/draft_b_text per candidate, no single recommended
|
|
67
|
+
reply). Checking only "reply_text" made every post-redesign orphaned
|
|
68
|
+
result silently misclassified as non-prep and marked .skipped instead of
|
|
69
|
+
recovered — the exact "worker drafted but no card" bug this script exists
|
|
70
|
+
to prevent. Accept either field so both old and current schema results
|
|
71
|
+
are recognized.
|
|
72
|
+
"""
|
|
64
73
|
if not isinstance(obj, dict):
|
|
65
74
|
return False
|
|
66
75
|
cands = obj.get("candidates")
|
|
67
76
|
if not isinstance(cands, list) or not cands:
|
|
68
77
|
return False
|
|
69
78
|
c0 = cands[0]
|
|
70
|
-
|
|
79
|
+
if not isinstance(c0, dict):
|
|
80
|
+
return False
|
|
81
|
+
has_text = "reply_text" in c0 or "draft_a_text" in c0
|
|
82
|
+
return has_text and ("candidate_url" in c0 or "candidate_id" in c0)
|
|
71
83
|
|
|
72
84
|
|
|
73
85
|
def main():
|