@m13v/s4l 1.7.8 → 1.7.9-rc.1

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 CHANGED
@@ -3636,14 +3636,27 @@ function writeDraftProvider(provider, setBy) {
3636
3636
  console.error(`[draft-provider] ${provider} (${setBy})`);
3637
3637
  }
3638
3638
  tool("queue_setup", {
3639
- title: "Get autopilot scheduled-task specs",
3640
- description: "Returns the scheduled task that runs the hands-free draft autopilot on this machine " +
3641
- "(s4l-worker, the universal queue worker). For EACH returned task, call the host tool " +
3642
- "create_scheduled_task with its taskId, cronExpression, prompt, and notifyOnCompletion " +
3643
- "VERBATIM (do not edit the prompt it contains exact local paths; notifyOnCompletion MUST be " +
3644
- "false or the per-minute worker spams a notification every run). The task drains the local job queue that the " +
3645
- "real pipeline feeds (all job types); the pipeline itself is kicked by launchd jobs this server " +
3646
- "installs. Use this as the final onboarding step instead of the old per-type worker tasks.",
3639
+ // Title/description are host-aware (2026-08-06): an agent reads the tool
3640
+ // description FIRST, so it must tell the truth for the host it's on.
3641
+ // Historic name kept for fleet compatibility; conceptually this tool is
3642
+ // "arm the drafting engine" Claude hosts get queue-worker task specs,
3643
+ // Codex/ChatGPT hosts get the provider stamped with nothing to schedule.
3644
+ title: s4lHost() === "codex"
3645
+ ? "Arm the draft autopilot"
3646
+ : "Get autopilot scheduled-task specs",
3647
+ description: s4lHost() === "codex"
3648
+ ? "Arms the hands-free draft autopilot on this machine. On this host there is NOTHING to " +
3649
+ "schedule: drafting runs inline through this app's engine, so ONE call completes autopilot " +
3650
+ "setup (it records the draft engine choice and returns no tasks). Do NOT create any " +
3651
+ "scheduled task or automation. The pipeline itself is kicked by launchd jobs this server " +
3652
+ "installs. Use this as the final onboarding step."
3653
+ : "Returns the scheduled task that runs the hands-free draft autopilot on this machine " +
3654
+ "(s4l-worker, the universal queue worker). For EACH returned task, call the host tool " +
3655
+ "create_scheduled_task with its taskId, cronExpression, prompt, and notifyOnCompletion " +
3656
+ "VERBATIM (do not edit the prompt — it contains exact local paths; notifyOnCompletion MUST be " +
3657
+ "false or the per-minute worker spams a notification every run). The task drains the local job queue that the " +
3658
+ "real pipeline feeds (all job types); the pipeline itself is kicked by launchd jobs this server " +
3659
+ "installs. Use this as the final onboarding step instead of the old per-type worker tasks.",
3647
3660
  inputSchema: {},
3648
3661
  }, async () => {
3649
3662
  // Codex/ChatGPT host: there is no scheduled-task worker at all. Drafting
@@ -1,4 +1,4 @@
1
1
  {
2
- "version": "1.7.8",
3
- "installedAt": "2026-08-07T17:57:02.547Z"
2
+ "version": "1.7.9-rc.1",
3
+ "installedAt": "2026-08-07T20:23:25.293Z"
4
4
  }
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.8",
5
+ "version": "1.7.9-rc.1",
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": {
@@ -72,10 +72,6 @@
72
72
  "name": "client_event",
73
73
  "description": "Log a lightweight client UI event"
74
74
  },
75
- {
76
- "name": "queue_setup",
77
- "description": "Get autopilot scheduled-task specs"
78
- },
79
75
  {
80
76
  "name": "dashboard",
81
77
  "description": "S4L dashboard"
@@ -157,12 +157,16 @@ class _Worker(threading.Thread):
157
157
  # focus back to the app the user was in. Screenshots/clicks are
158
158
  # unaffected (CDP is offscreen-raster + synthetic input; the occlusion
159
159
  # flags keep hidden tabs painting).
160
- # DEFAULT OFF (user decision 2026-07-30): only the telemetry above runs
161
- # unless S4L_HARNESS_HIDE=1 opts in. S4L_NO_HARNESS_HIDE force-disables
162
- # even when the opt-in is set.
160
+ # DEFAULT ON (user decision 2026-08-07, reverses the 2026-07-30 default-off
161
+ # call): the guard hides an offscreen harness that steals the foreground
162
+ # unless explicitly opted out. Two knobs, by design:
163
+ # S4L_NO_HARNESS_HIDE -> HARD override, force off, checked FIRST so it
164
+ # always wins (this is the one-time interactive-login escape hatch).
165
+ # S4L_HARNESS_HIDE=0 -> SOFT opt-out for a machine that wants it off.
166
+ # Unset or any non-"0" value => hide is active (the new default).
163
167
  if os.environ.get("S4L_NO_HARNESS_HIDE"):
164
168
  return
165
- if os.environ.get("S4L_HARNESS_HIDE") != "1":
169
+ if os.environ.get("S4L_HARNESS_HIDE", "1") == "0":
166
170
  return
167
171
  pos = details.get("window_position") or ""
168
172
  try:
package/mcp/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@m13v/s4l-mcp",
3
- "version": "1.7.8",
3
+ "version": "1.7.9-rc.1",
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@m13v/s4l",
3
- "version": "1.7.8",
3
+ "version": "1.7.9-rc.1",
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",
@@ -1,8 +1,27 @@
1
1
  #!/usr/bin/env python3
2
2
  """
3
- claude_job.py — queue-backed substitute for `claude -p` for the pipeline's
4
- pure text->JSON turns, on every machine (operator Macs and customer .mcpb
5
- boxes alike).
3
+ claude_job.py — THE DRAFT-ENGINE SEAM: every pure text->JSON drafting turn in
4
+ the pipeline lands here, and <state_dir>/draft-provider.json decides which
5
+ engine answers it (see scripts/draft_provider.py; design + verified facts in
6
+ docs/codex-port-design.md):
7
+
8
+ claude-desktop-queue (default) enqueue to a file queue drained by the
9
+ Claude Desktop s4l-worker scheduled task — the
10
+ original design, and the only option when Claude
11
+ Desktop is the box's sole authenticated engine.
12
+ claude-p answer inline via the real `claude -p` (_run_claude_p;
13
+ schema INLINED — the CLI parses --json-schema as JSON,
14
+ a file path breaks it).
15
+ codex-exec answer inline via the ChatGPT-app-bundled `codex exec`
16
+ (_run_codex_exec; gpt-5.6-sol default, schema rides
17
+ the prompt — OpenAI strict schema mode rejects our
18
+ lenient schemas).
19
+
20
+ All three return byte-identical claude `--output-format json` envelopes and
21
+ the same 0/1/79 exit semantics, so callers can't tell them apart. The queue
22
+ machinery below (next/result, worker notes, heartbeats) only runs for the
23
+ default provider; the inline providers skip it entirely, which also means no
24
+ warm-session leaks and no app-open requirement on those paths.
6
25
 
7
26
  The deterministic pipeline never calls `claude` directly; every invocation goes
8
27
  through scripts/run_claude.sh. For script tags mapped in TAG_TO_TYPE below,
@@ -461,19 +480,22 @@ def _bump_drain_timeout() -> None:
461
480
 
462
481
 
463
482
  # --------------------------------------------------------------------------- #
464
- # Opt-in worker self-reap (2026-06-27) #
483
+ # Worker self-reap (2026-06-27; DEFAULT ON since 2026-07-04 / v1.6.202) #
465
484
  # --------------------------------------------------------------------------- #
466
485
  # A scheduled-task worker turn finishes its one queue iteration but Claude
467
486
  # Desktop keeps the agent-mode `claude` process warm (`--input-format
468
487
  # stream-json`), so finished workers pile up and leak RAM. The launchd reaper
469
- # (reap_stale_claude_sessions.py) is the GUARANTEE that bounds this. This opt-in
488
+ # (reap_stale_claude_sessions.py) is the GUARANTEE that bounds this. This
470
489
  # path is a faster, source-side trim: once THIS worker is provably done (no work
471
490
  # to do, or its result is already on disk), terminate OUR OWN session so it never
472
- # becomes part of the standing pool. Strictly off unless S4L_WORKER_SELF_REAP is
473
- # set, so it ships dormant and cannot destabilize the default behaviour.
491
+ # becomes part of the standing pool. It shipped opt-in (dormant unless
492
+ # S4L_WORKER_SELF_REAP was set), which meant it ran nowhere; when Desktop
493
+ # 1.18286.0 changed the cmdline shape the signature-fragile reaper missed too
494
+ # and boxes leaked (Karol, 53 piled workers). Since 2026-07-04 it is ON by
495
+ # default; opt OUT with S4L_WORKER_SELF_REAP=0 (see _self_reap_enabled).
474
496
  #
475
497
  # Safety properties:
476
- # * No-op unless the env flag is set.
498
+ # * Respects the env kill switch (S4L_WORKER_SELF_REAP=0 disables it).
477
499
  # * Only ever targets a process in OUR OWN ancestry that matches the reaper's
478
500
  # worker signature (claude-code agent-mode session). The producer side
479
501
  # (run-twitter-cycle.sh -> python) has no such ancestor, so a misplaced call