social-autoposter 1.6.30 → 1.6.31

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 (72) hide show
  1. package/mcp/dist/index.js +83 -0
  2. package/mcp/dist/panel.html +118 -0
  3. package/mcp/manifest.json +4 -0
  4. package/package.json +67 -1
  5. package/skill/invent-supply-test.sh +4 -2
  6. package/skill/run-twitter-cycle.sh +4 -2
  7. package/scripts/_dm_icp_batch.py +0 -44
  8. package/scripts/_li_discover_pending.py +0 -156
  9. package/scripts/_phaseA_build_envelope.py +0 -135
  10. package/scripts/_phaseA_select_5AI7GO.py +0 -191
  11. package/scripts/_scan_aggregate.py +0 -108
  12. package/scripts/_scan_timeline.py +0 -85
  13. package/scripts/_serp_report.py +0 -223
  14. package/scripts/_serp_vs_gsc_report.py +0 -253
  15. package/scripts/_test_since_hook.py +0 -117
  16. package/scripts/add_deploy_metadata.py +0 -70
  17. package/scripts/add_nightowl_to_config.py +0 -521
  18. package/scripts/amplitude_user_lookup.py +0 -221
  19. package/scripts/audit_signup_wiring.py +0 -202
  20. package/scripts/backfill_aggregate_stats.py +0 -143
  21. package/scripts/backfill_claude_session_subagents.py +0 -290
  22. package/scripts/backfill_crossroute_attribution.py +0 -136
  23. package/scripts/backfill_ensure_dms.py +0 -132
  24. package/scripts/backfill_icp_precheck.py +0 -231
  25. package/scripts/backfill_linkedin_activity_urns.py +0 -448
  26. package/scripts/backfill_mk0r_get_started.py +0 -163
  27. package/scripts/backfill_run_monitor.py +0 -299
  28. package/scripts/backfill_seo_authors.py +0 -241
  29. package/scripts/backfill_seo_engagement.py +0 -299
  30. package/scripts/backfill_target_project.py +0 -112
  31. package/scripts/blog_refactor_single_route.py +0 -196
  32. package/scripts/browser_watch.py +0 -145
  33. package/scripts/check_analytics_wiring.py +0 -873
  34. package/scripts/check_backfill_replied.py +0 -107
  35. package/scripts/check_contrast.py +0 -425
  36. package/scripts/check_deploy_wiring.py +0 -138
  37. package/scripts/check_layout_wiring.py +0 -287
  38. package/scripts/check_link_rules.py +0 -101
  39. package/scripts/check_pep604_annotations.py +0 -163
  40. package/scripts/cleanup_moltbook_dupes_16060.py +0 -146
  41. package/scripts/cohort_score_distribution.py +0 -112
  42. package/scripts/daily_stats_email.py +0 -410
  43. package/scripts/delete_twitter_posts.py +0 -272
  44. package/scripts/dm_helper.py +0 -47
  45. package/scripts/export_cdp_storage_state.py +0 -190
  46. package/scripts/export_kent_handoff.py +0 -62
  47. package/scripts/extract_user_messages_today.py +0 -291
  48. package/scripts/fazm_seo_health.py +0 -109
  49. package/scripts/fetch_twitter_t1.py +0 -134
  50. package/scripts/fix_mdx_light_mode.py +0 -73
  51. package/scripts/fix_style_lengths_20260601.py +0 -93
  52. package/scripts/fix_svg_paragraph_wrap.py +0 -59
  53. package/scripts/ig_collate_transcripts.py +0 -62
  54. package/scripts/ingest_human_seo_replies.py +0 -280
  55. package/scripts/install_lane_digest.py +0 -201
  56. package/scripts/li_process_notifications.py +0 -149
  57. package/scripts/li_process_notifs.py +0 -69
  58. package/scripts/octolens_threads.py +0 -315
  59. package/scripts/octolens_twitter_batch.py +0 -210
  60. package/scripts/octolens_twitter_cdp.py +0 -165
  61. package/scripts/poll_web_chat.py +0 -72
  62. package/scripts/process_li_notifs.py +0 -140
  63. package/scripts/project_deploy_status.py +0 -272
  64. package/scripts/regenerate_ig_plists.py +0 -319
  65. package/scripts/send_comment_replies.py +0 -110
  66. package/scripts/seo_health_all_projects.py +0 -94
  67. package/scripts/snapshot_style_targets.py +0 -85
  68. package/scripts/socialcrawl.py +0 -116
  69. package/scripts/sweep_guide_chrome.py +0 -212
  70. package/scripts/sync_web_chat_config.py +0 -144
  71. package/scripts/test_own_reply_dedup.py +0 -56
  72. 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);