social-autoposter 1.6.95 → 1.6.97
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 +9 -0
- package/mcp/dist/version.json +2 -2
- package/mcp/manifest.json +1 -1
- package/mcp/package.json +1 -1
- package/package.json +1 -1
- package/scripts/link_tail.py +26 -0
- package/scripts/twitter_post_plan.py +9 -4
package/mcp/dist/index.js
CHANGED
|
@@ -687,6 +687,15 @@ async function postApproved(batchId, plan) {
|
|
|
687
687
|
// with override, so nothing clobbers it. Cron is untouched (it never goes
|
|
688
688
|
// through this MCP path), so the 0.9 experiment keeps running there.
|
|
689
689
|
TWITTER_TAIL_LINK_RATE: "1.0",
|
|
690
|
+
// Plugin flow only: skip the link_tail Claude call. It just rewords
|
|
691
|
+
// prose around the URL (the minted short link comes from the
|
|
692
|
+
// deterministic wrap step), and on .mcpb boxes there's no `claude`
|
|
693
|
+
// binary so it wastes ~35s/post of run_claude.sh retry backoff before
|
|
694
|
+
// falling back to the mechanical concat anyway. link_tail.py honors
|
|
695
|
+
// this and short-circuits to that concat instantly. The local
|
|
696
|
+
// cron/plist autopilot never sets this, so it keeps generating the
|
|
697
|
+
// bridge sentence.
|
|
698
|
+
SAPS_SKIP_LINK_TAIL: "1",
|
|
690
699
|
// The poster attaches to the twitter-harness Chrome over CDP. The cron
|
|
691
700
|
// pipeline exports this from skill/lib/twitter-backend.sh; the MCP path
|
|
692
701
|
// must set it explicitly or twitter_browser.py fails with "No twitter-
|
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.6.
|
|
5
|
+
"version": "1.6.97",
|
|
6
6
|
"description": "Draft, review, approve, and autopilot X/Twitter posts. Thin desktop client over the S4L pipeline.",
|
|
7
7
|
"long_description": "A guided assistant that drafts, reviews, and autopilots X/Twitter posts.\nTo get started:\n1. Click **Configure** and set every tool permission to **Always Allow**.\n2. Copy this prompt: **Set me up on S4L end to end**.\n3. Quit fully with CMD+Q, restart Claude, and paste the prompt into a new chat.",
|
|
8
8
|
"author": {
|
package/mcp/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@m13v/social-autoposter-mcp",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.97",
|
|
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
package/scripts/link_tail.py
CHANGED
|
@@ -461,6 +461,32 @@ def main() -> int:
|
|
|
461
461
|
print(json.dumps(out), flush=True)
|
|
462
462
|
return 0
|
|
463
463
|
|
|
464
|
+
# Plugin (MCP post_drafts) flow sets SAPS_SKIP_LINK_TAIL=1. The bridge only
|
|
465
|
+
# rewords prose around the URL — the minted short link is produced by a
|
|
466
|
+
# separate deterministic wrap step in twitter_post_plan.py — so the Claude
|
|
467
|
+
# call buys nothing there, and on .mcpb customer boxes (no `claude` binary)
|
|
468
|
+
# it burns ~35s of run_claude.sh retry backoff per post before falling back
|
|
469
|
+
# to this exact mechanical concat. Short-circuit straight to the concat.
|
|
470
|
+
# The local cron/plist autopilot leaves this env unset and still generates
|
|
471
|
+
# the bridge sentence.
|
|
472
|
+
if os.environ.get("SAPS_SKIP_LINK_TAIL") == "1":
|
|
473
|
+
limit = TWEET_LIMIT if args.platform == "twitter" else None
|
|
474
|
+
fb_text, fb_trim = enforce_budget(
|
|
475
|
+
mechanical_fallback(reply_text, link_url), link_url,
|
|
476
|
+
limit if limit is not None else TWEET_LIMIT * 100)
|
|
477
|
+
out = {
|
|
478
|
+
"ok": True,
|
|
479
|
+
"text": fb_text,
|
|
480
|
+
"tail": link_url,
|
|
481
|
+
"model_call_ok": False,
|
|
482
|
+
"fallback_used": True,
|
|
483
|
+
"budget_trimmed": fb_trim,
|
|
484
|
+
"error": "skipped_plugin_flow",
|
|
485
|
+
"elapsed_sec": 0.0,
|
|
486
|
+
}
|
|
487
|
+
print(json.dumps(out), flush=True)
|
|
488
|
+
return 0
|
|
489
|
+
|
|
464
490
|
voice_relationship = args.voice_relationship or resolve_voice_relationship(args.project)
|
|
465
491
|
# Length cap is X-specific; reddit/linkedin pass None (no tail trim).
|
|
466
492
|
limit = TWEET_LIMIT if args.platform == "twitter" else None
|
|
@@ -1055,9 +1055,13 @@ def main() -> int:
|
|
|
1055
1055
|
|
|
1056
1056
|
try:
|
|
1057
1057
|
for _idx, c in enumerate(candidates, start=1):
|
|
1058
|
-
# Live per-post status for the S4L menu bar
|
|
1059
|
-
#
|
|
1060
|
-
|
|
1058
|
+
# Live per-post status for the S4L menu bar. LEAD with `posted` (the
|
|
1059
|
+
# REAL count of replies that actually landed), not `_idx` (the loop
|
|
1060
|
+
# position). _idx races through already-posted / deleted cards as instant
|
|
1061
|
+
# dedup-skips, so a bare "posting 88/139" looked like 88 were sent when
|
|
1062
|
+
# 0 were — misleading on every restart. "{posted} sent · {_idx}/{_total}"
|
|
1063
|
+
# keeps the honest number in front; the position is secondary context.
|
|
1064
|
+
_write_activity(f"posting {posted} sent · {_idx}/{_total}")
|
|
1061
1065
|
# Re-stamp the batch hold at each candidate boundary so the
|
|
1062
1066
|
# POST_LOCK_EXPIRY failsafe measures silence from the LAST real
|
|
1063
1067
|
# progress, not from batch start. Insurance on top of the child's own
|
|
@@ -1082,7 +1086,8 @@ def main() -> int:
|
|
|
1082
1086
|
posted += 1
|
|
1083
1087
|
# Flash the confirmation with a short dwell so the menu bar shows
|
|
1084
1088
|
# it before the next iteration's "posting" overwrites the label.
|
|
1085
|
-
|
|
1089
|
+
# `posted` was just incremented, so it reflects the reply that landed.
|
|
1090
|
+
_write_activity(f"posting {posted} sent ✓ · {_idx}/{_total}")
|
|
1086
1091
|
time.sleep(0.6)
|
|
1087
1092
|
elif outcome == "skipped":
|
|
1088
1093
|
skipped += 1
|