social-autoposter 1.6.30 → 1.6.32

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.
Files changed (77) hide show
  1. package/mcp/dist/index.js +83 -0
  2. package/mcp/dist/panel.html +118 -0
  3. package/mcp/manifest.json +6 -1
  4. package/mcp-servers/browser-harness/server.py +81 -19
  5. package/package.json +71 -2
  6. package/skill/invent-supply-test.sh +3 -0
  7. package/skill/run-twitter-cycle.sh +47 -0
  8. package/mcp-servers/browser-harness/__pycache__/server.cpython-311.pyc +0 -0
  9. package/mcp-servers/browser-harness/__pycache__/server.cpython-314.pyc +0 -0
  10. package/mcp-servers/browser-harness/__pycache__/server.cpython-39.pyc +0 -0
  11. package/scripts/_dm_icp_batch.py +0 -44
  12. package/scripts/_dm_icp_batch.sh +0 -32
  13. package/scripts/_li_discover_pending.py +0 -156
  14. package/scripts/_phaseA_build_envelope.py +0 -135
  15. package/scripts/_phaseA_select_5AI7GO.py +0 -191
  16. package/scripts/_scan_aggregate.py +0 -108
  17. package/scripts/_scan_timeline.py +0 -85
  18. package/scripts/_serp_report.py +0 -223
  19. package/scripts/_serp_vs_gsc_report.py +0 -253
  20. package/scripts/_test_since_hook.py +0 -117
  21. package/scripts/add_deploy_metadata.py +0 -70
  22. package/scripts/add_nightowl_to_config.py +0 -521
  23. package/scripts/amplitude_user_lookup.py +0 -221
  24. package/scripts/audit_signup_wiring.py +0 -202
  25. package/scripts/backfill_aggregate_stats.py +0 -143
  26. package/scripts/backfill_claude_session_subagents.py +0 -290
  27. package/scripts/backfill_crossroute_attribution.py +0 -136
  28. package/scripts/backfill_ensure_dms.py +0 -132
  29. package/scripts/backfill_icp_precheck.py +0 -231
  30. package/scripts/backfill_linkedin_activity_urns.py +0 -448
  31. package/scripts/backfill_mk0r_get_started.py +0 -163
  32. package/scripts/backfill_run_monitor.py +0 -299
  33. package/scripts/backfill_seo_authors.py +0 -241
  34. package/scripts/backfill_seo_engagement.py +0 -299
  35. package/scripts/backfill_target_project.py +0 -112
  36. package/scripts/blog_refactor_single_route.py +0 -196
  37. package/scripts/browser_watch.py +0 -145
  38. package/scripts/check_analytics_wiring.py +0 -873
  39. package/scripts/check_backfill_replied.py +0 -107
  40. package/scripts/check_contrast.py +0 -425
  41. package/scripts/check_deploy_wiring.py +0 -138
  42. package/scripts/check_layout_wiring.py +0 -287
  43. package/scripts/check_link_rules.py +0 -101
  44. package/scripts/check_pep604_annotations.py +0 -163
  45. package/scripts/cleanup_moltbook_dupes_16060.py +0 -146
  46. package/scripts/cohort_score_distribution.py +0 -112
  47. package/scripts/daily_stats_email.py +0 -410
  48. package/scripts/delete_twitter_posts.py +0 -272
  49. package/scripts/dm_helper.py +0 -47
  50. package/scripts/export_cdp_storage_state.py +0 -190
  51. package/scripts/export_kent_handoff.py +0 -62
  52. package/scripts/extract_user_messages_today.py +0 -291
  53. package/scripts/fazm_seo_health.py +0 -109
  54. package/scripts/fetch_twitter_t1.py +0 -134
  55. package/scripts/fix_mdx_light_mode.py +0 -73
  56. package/scripts/fix_style_lengths_20260601.py +0 -93
  57. package/scripts/fix_svg_paragraph_wrap.py +0 -59
  58. package/scripts/ig_collate_transcripts.py +0 -62
  59. package/scripts/ingest_human_seo_replies.py +0 -280
  60. package/scripts/install_lane_digest.py +0 -201
  61. package/scripts/li_process_notifications.py +0 -149
  62. package/scripts/li_process_notifs.py +0 -69
  63. package/scripts/octolens_threads.py +0 -315
  64. package/scripts/octolens_twitter_batch.py +0 -210
  65. package/scripts/octolens_twitter_cdp.py +0 -165
  66. package/scripts/poll_web_chat.py +0 -72
  67. package/scripts/process_li_notifs.py +0 -140
  68. package/scripts/project_deploy_status.py +0 -272
  69. package/scripts/regenerate_ig_plists.py +0 -319
  70. package/scripts/send_comment_replies.py +0 -110
  71. package/scripts/seo_health_all_projects.py +0 -94
  72. package/scripts/snapshot_style_targets.py +0 -85
  73. package/scripts/socialcrawl.py +0 -116
  74. package/scripts/sweep_guide_chrome.py +0 -212
  75. package/scripts/sync_web_chat_config.py +0 -144
  76. package/scripts/test_own_reply_dedup.py +0 -56
  77. package/scripts/twitter_compose_dm.py +0 -332
package/mcp/dist/index.js CHANGED
@@ -19,6 +19,12 @@ import { REPO_DIR, runPython, run, readPlan, writePlan, planPath, latestBatchId,
19
19
  import { applySetup, resolveProject, hasReadyProject, listManagedProjectStatus, REQUIRED_FIELDS, RECOMMENDED_FIELDS, CONFIG_PATH, } from "./setup.js";
20
20
  import { xStatus, xConnect, summarizeXAuth } from "./twitterAuth.js";
21
21
  import { VERSION, versionStatus, latestPublishedVersion } from "./version.js";
22
+ import { registerAppTool, registerAppResource, RESOURCE_MIME_TYPE, } from "@modelcontextprotocol/ext-apps/server";
23
+ import { fileURLToPath } from "node:url";
24
+ // MCP Apps control panel. The self-contained HTML is built by vite
25
+ // (vite-plugin-singlefile) into dist/panel.html alongside this compiled file.
26
+ const DIST_DIR = path.dirname(fileURLToPath(import.meta.url));
27
+ const PANEL_URI = "ui://social-autoposter/panel.html";
22
28
  const TWITTER_AUTOPILOT_LABEL = "com.m13v.social-twitter-cycle";
23
29
  const TWITTER_AUTOPILOT_PLIST = path.join(os.homedir(), "Library", "LaunchAgents", `${TWITTER_AUTOPILOT_LABEL}.plist`);
24
30
  // Daily self-updater. Enabled alongside autopilot so a hands-free (headless)
@@ -670,6 +676,83 @@ server.registerTool("version", {
670
676
  : "You are on the latest published version.",
671
677
  });
672
678
  });
679
+ // ---- panel: MCP Apps control surface --------------------------------------
680
+ // A self-contained HTML view rendered by hosts that support MCP Apps (Claude
681
+ // desktop/web, etc.). It duplicates NO pipeline logic: each button calls one of
682
+ // the tools above (draft_cycle / autopilot / setup / get_stats) through the host
683
+ // and re-reads status. The tool itself returns the first-paint snapshot so the
684
+ // view has data the instant it loads.
685
+ // Is either launchd job (cycle / daily updater) currently loaded?
686
+ async function autopilotLoaded() {
687
+ try {
688
+ const res = await run("launchctl", ["list"], { timeoutMs: 10_000 });
689
+ const lines = res.stdout.split("\n");
690
+ return {
691
+ autopilot_on: lines.some((l) => l.includes(TWITTER_AUTOPILOT_LABEL)),
692
+ auto_update_on: lines.some((l) => l.includes(UPDATER_LABEL)),
693
+ };
694
+ }
695
+ catch {
696
+ return { autopilot_on: false, auto_update_on: false };
697
+ }
698
+ }
699
+ // Assemble everything the panel needs in one shot (projects + X + autopilot +
700
+ // version). Resilient: any probe that throws degrades to a safe default rather
701
+ // than failing the whole snapshot.
702
+ async function buildSnapshot() {
703
+ const projects = listManagedProjectStatus().map((p) => ({
704
+ name: p.name,
705
+ ready: p.ready,
706
+ missing_required: p.missing_required,
707
+ }));
708
+ const [x, ap, ver] = await Promise.all([
709
+ xStatus().catch(() => ({ connected: false, state: "" })),
710
+ autopilotLoaded(),
711
+ versionStatus().catch(() => ({ installed: VERSION, latest: null, update_available: false })),
712
+ ]);
713
+ return {
714
+ projects,
715
+ projects_total: projects.length,
716
+ projects_ready: projects.filter((p) => p.ready).length,
717
+ x_connected: !!x.connected,
718
+ x_state: x.state || "",
719
+ autopilot_on: ap.autopilot_on,
720
+ auto_update_on: ap.auto_update_on,
721
+ version: ver.installed || VERSION,
722
+ latest_version: ver.latest ?? null,
723
+ update_available: !!ver.update_available,
724
+ };
725
+ }
726
+ registerAppTool(server, "panel", {
727
+ title: "Social Autoposter panel",
728
+ description: "Open the Social Autoposter control panel: a visual dashboard showing project setup, X " +
729
+ "connection, autopilot state, and 7-day stats, with buttons to run a draft cycle, toggle " +
730
+ "autopilot, connect X, and refresh. Use when the user asks to see the panel, dashboard, " +
731
+ "status, or controls. Hosts without UI support get the same data as text.",
732
+ inputSchema: {},
733
+ outputSchema: { snapshot: z.string() },
734
+ _meta: { ui: { resourceUri: PANEL_URI } },
735
+ }, async () => {
736
+ const snap = await buildSnapshot();
737
+ const human = `Social Autoposter v${snap.version}` +
738
+ (snap.update_available && snap.latest_version ? ` (update to ${snap.latest_version})` : "") +
739
+ ` — projects ${snap.projects_ready}/${snap.projects_total} ready, ` +
740
+ `X ${snap.x_connected ? "connected" : "not connected"}, ` +
741
+ `autopilot ${snap.autopilot_on ? "on" : "off"}.`;
742
+ return {
743
+ content: [{ type: "text", text: human }],
744
+ structuredContent: { snapshot: JSON.stringify(snap) },
745
+ };
746
+ });
747
+ registerAppResource(server, "Social Autoposter panel", PANEL_URI, { mimeType: RESOURCE_MIME_TYPE }, async () => ({
748
+ contents: [
749
+ {
750
+ uri: PANEL_URI,
751
+ mimeType: RESOURCE_MIME_TYPE,
752
+ text: fs.readFileSync(path.join(DIST_DIR, "panel.html"), "utf-8"),
753
+ },
754
+ ],
755
+ }));
673
756
  async function main() {
674
757
  const transport = new StdioServerTransport();
675
758
  await server.connect(transport);