social-autoposter 1.6.47 → 1.6.48

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "social-autoposter",
3
- "version": "1.6.47",
3
+ "version": "1.6.48",
4
4
  "description": "Automated social posting pipeline for Reddit, X/Twitter, LinkedIn, and Moltbook. Install as a Claude Code agent skill.",
5
5
  "bin": {
6
6
  "social-autoposter": "bin/cli.js"
@@ -36,8 +36,21 @@ def main() -> int:
36
36
  if len(pages) <= 1:
37
37
  print(f"[cleanup_harness_tabs] {len(pages)} page tab(s), no cleanup needed")
38
38
  return 0
39
+ # Keep a REAL (http/https) tab when one exists, not blindly pages[0]. The
40
+ # /json order is roughly most-recently-active first, so a freshly-spawned
41
+ # about:blank can sit at index 0 and the old code would keep the blank and
42
+ # close the live x.com tab the harness daemon is attached to. Closing the
43
+ # daemon's tab forces it to re-attach and re-spawn another about:blank, which
44
+ # is exactly the orphan-tab churn this script is meant to clean up. Falling
45
+ # back to pages[0] preserves the prior behavior when every tab is blank.
46
+ def _is_real(t):
47
+ return (t.get("url") or "").startswith(("http://", "https://"))
48
+
49
+ keep = next((t for t in pages if _is_real(t)), pages[0])
39
50
  closed = 0
40
- for t in pages[1:]:
51
+ for t in pages:
52
+ if t is keep:
53
+ continue
41
54
  tid = t.get("id")
42
55
  if not tid:
43
56
  continue
@@ -46,7 +59,8 @@ def main() -> int:
46
59
  closed += 1
47
60
  except Exception:
48
61
  pass
49
- print(f"[cleanup_harness_tabs] closed {closed}/{len(pages) - 1} extra page tabs (kept 1)")
62
+ kept_kind = "1 real" if _is_real(keep) else "1"
63
+ print(f"[cleanup_harness_tabs] closed {closed}/{len(pages) - 1} extra page tabs (kept {kept_kind})")
50
64
  return 0
51
65
 
52
66
 
@@ -243,14 +243,35 @@ def main():
243
243
  continue
244
244
  bank = build_bank(name, args.min_likes, args.min_clicks, args.limit)
245
245
  proven_size = len(bank)
246
+ invent_added = 0
246
247
  if not args.no_invented:
247
248
  invented = fetch_invented_queries(name, args.invent_min_supply)
248
249
  bank = merge_invented(bank, invented)
250
+ invent_added = len(bank) - proven_size
251
+ # Cold-start bootstrap: a freshly-configured project has no proven
252
+ # queries (no post history) AND no invented ones (invent_topics.py
253
+ # hasn't run for it yet), so the bank is empty -> the cycle scans
254
+ # nothing and returns 0 drafts on every early cycle (the dead-on-
255
+ # arrival problem). Fall back to the project's seeded search_topic AS
256
+ # the query so there's something to scrape on day one. Proven +
257
+ # invented queries supersede this automatically as they accumulate.
258
+ # (cold-start fallback, 2026-06-03)
259
+ cold_start = False
260
+ if not bank:
261
+ topic = ((p.get("search_topic") if isinstance(p, dict) else "") or "").strip()
262
+ if topic:
263
+ bank = [{
264
+ "project": name,
265
+ "query": f"{topic} -filter:replies",
266
+ "search_topic": topic,
267
+ "likes": 0, "clicks": 0, "posts": 0,
268
+ }]
269
+ cold_start = True
249
270
  combined.extend(bank)
250
- invent_added = len(bank) - proven_size
251
271
  print(f"qualified_query_bank: project={name!r} -> {proven_size} proven "
252
- f"+ {invent_added} invented = {len(bank)} queries",
253
- file=sys.stderr)
272
+ f"+ {invent_added} invented"
273
+ + (" + 1 cold-start(topic)" if cold_start else "")
274
+ + f" = {len(bank)} queries", file=sys.stderr)
254
275
  json.dump(combined, sys.stdout)
255
276
  print()
256
277
  print(f"qualified_query_bank: combined bank = {len(combined)} queries across "