/**
 * Platform actions catalog — single source of truth for what's surfaced
 * on the Automations page under "Platform actions."
 *
 * Each entry is an in-browser action triggered by clicking the floating
 * launcher's button on the corresponding platform (linkedin.com, x.com,
 * web.telegram.org). These differ from the 23 backend preset workflows
 * in /api/workflows — those run as cron-driven engines on the server;
 * platform actions run in the page via content scripts.
 *
 * Source MENU_ITEMS arrays:
 *   chrome-extension/content-linkedin.js:2105  (9 items)
 *   chrome-extension/content-twitter.js:845   (15 items)
 *   chrome-extension/content-telegram.js:240  (5 items, "Dashboard"
 *                                              omitted as it's a meta-link)
 *
 * To add a new platform action:
 *   1) Add it to the platform's content-script MENU_ITEMS array
 *   2) Add an entry here with id matching that of the menu item
 *   3) Optionally hand-author a moduleMap (the read-only DAG shown in
 *      the viewer drawer). Without one the card shows "Module map: TBD".
 *
 * The moduleMap shape mirrors nexus-bot/src/workflow/presets/*.json
 * (nodes + connections). Node types should reference existing registry
 * entries (e.g. "trigger.manual", "logic.loop") OR the new "browser.*"
 * types that were added to nexus-bot/src/workflow/nodes.js for these.
 */

window.PLATFORM_ACTIONS = [
  // ─────────────────────────────────────────────────────────────────────
  // LINKEDIN (9)
  // ─────────────────────────────────────────────────────────────────────
  {
    id: "li_watchlist",
    platform: "linkedin",
    category: "intelligence",
    label: "Company Watchlist",
    description: "Monitor target companies and surface new employees / job changes / posts so you can act on warm intros.",
    launchUrl: "https://www.linkedin.com",
    moduleMap: {
      nodes: [
        { id: "n1", type: "trigger.manual",            name: "User clicks Company Watchlist" },
        { id: "n2", type: "db.query",                  name: "Load watchlist companies" },
        { id: "n3", type: "logic.loop",                name: "For each company" },
        { id: "n4", type: "browser.scan_feed",         name: "Check company page for new posts / hires" },
        { id: "n5", type: "ai.match_icp",              name: "AI: any signal worth surfacing?" },
        { id: "n6", type: "logic.if",                  name: "Has new signal?" },
        { id: "n7", type: "notify.telegram_user",      name: "Notify operator" },
        { id: "n8", type: "db.record_event",           name: "Log watchlist hit" },
      ],
      connections: {
        n1: { main: [[{ node: "n2", index: 0 }]] },
        n2: { main: [[{ node: "n3", index: 0 }]] },
        n3: { main: [[{ node: "n4", index: 0 }]] },
        n4: { main: [[{ node: "n5", index: 0 }]] },
        n5: { main: [[{ node: "n6", index: 0 }]] },
        n6: { main: [[{ node: "n7", index: 0 }], []] },
        n7: { main: [[{ node: "n8", index: 0 }]] },
      },
    },
  },
  {
    id: "li_competitor_siphon",
    platform: "linkedin",
    category: "intelligence",
    label: "Competitor Siphon",
    description: "Extract followers/engagers of a competitor's LinkedIn account and queue them for outreach.",
    launchUrl: "https://www.linkedin.com",
    moduleMap: {
      nodes: [
        { id: "n1", type: "trigger.manual",            name: "User clicks Competitor Siphon" },
        { id: "n2", type: "browser.parse_post_url",    name: "Parse competitor profile URL" },
        { id: "n3", type: "browser.scrape_followers",  name: "Scrape followers/engagers" },
        { id: "n4", type: "logic.loop",                name: "For each prospect" },
        { id: "n5", type: "db.upsert_contact",         name: "Upsert into shared_contacts" },
        { id: "n6", type: "db.record_event",     name: "Log to outreach_events" },
      ],
      connections: {
        n1: { main: [[{ node: "n2", index: 0 }]] },
        n2: { main: [[{ node: "n3", index: 0 }]] },
        n3: { main: [[{ node: "n4", index: 0 }]] },
        n4: { main: [[{ node: "n5", index: 0 }]] },
        n5: { main: [[{ node: "n6", index: 0 }]] },
      },
    },
  },
  {
    id: "li_add_connections",
    platform: "linkedin",
    category: "engagement",
    label: "Add Connections",
    description: "Search LinkedIn by keyword and bulk-send connect requests with personalized notes.",
    launchUrl: "https://www.linkedin.com",
    moduleMap: {
      nodes: [
        { id: "n1", type: "trigger.manual",          name: "User enters search keywords" },
        { id: "n2", type: "browser.search",          name: "Run LinkedIn people search" },
        { id: "n3", type: "browser.scrape_followers", name: "Scrape result list" },
        { id: "n4", type: "logic.loop",              name: "For each result" },
        { id: "n5", type: "logic.rate_limit",        name: "Daily connect cap?" },
        { id: "n6", type: "browser.send_connect",    name: "Send connect with note" },
        { id: "n7", type: "db.record_event",         name: "Log connect" },
      ],
      connections: {
        n1: { main: [[{ node: "n2", index: 0 }]] },
        n2: { main: [[{ node: "n3", index: 0 }]] },
        n3: { main: [[{ node: "n4", index: 0 }]] },
        n4: { main: [[{ node: "n5", index: 0 }]] },
        n5: { main: [[{ node: "n6", index: 0 }]] },
        n6: { main: [[{ node: "n7", index: 0 }]] },
      },
    },
  },
  {
    id: "li_connect_commenters",
    platform: "linkedin",
    category: "engagement",
    label: "Connect with Commenters",
    description: "Pull people who commented on a target post and send them connect requests with custom messages.",
    launchUrl: "https://www.linkedin.com",
    moduleMap: {
      nodes: [
        { id: "n1", type: "trigger.manual",             name: "User clicks Connect with Commenters" },
        { id: "n2", type: "browser.parse_post_url",     name: "Parse target post URL" },
        { id: "n3", type: "browser.scrape_commenters",  name: "Scrape commenter list" },
        { id: "n4", type: "logic.loop",                 name: "For each commenter" },
        { id: "n5", type: "browser.send_connect",       name: "Send connect request with note" },
        { id: "n6", type: "db.record_event",      name: "Log to outreach_events" },
      ],
      connections: {
        n1: { main: [[{ node: "n2", index: 0 }]] },
        n2: { main: [[{ node: "n3", index: 0 }]] },
        n3: { main: [[{ node: "n4", index: 0 }]] },
        n4: { main: [[{ node: "n5", index: 0 }]] },
        n5: { main: [[{ node: "n6", index: 0 }]] },
      },
    },
  },
  {
    id: "li_engage_feed",
    platform: "linkedin",
    category: "engagement",
    label: "Engage Feed",
    description: "Like and optionally comment on posts in your LinkedIn home feed using human-paced timing.",
    launchUrl: "https://www.linkedin.com/feed/",
    moduleMap: {
      nodes: [
        { id: "n1", type: "trigger.manual",       name: "User clicks Engage Feed" },
        { id: "n2", type: "browser.scan_feed",    name: "Scan home feed posts" },
        { id: "n3", type: "logic.loop",           name: "For each post" },
        { id: "n4", type: "logic.if",             name: "Skip own posts?" },
        { id: "n5", type: "browser.like_post",    name: "Like the post" },
        { id: "n6", type: "db.record_event", name: "Log engagement" },
      ],
      connections: {
        n1: { main: [[{ node: "n2", index: 0 }]] },
        n2: { main: [[{ node: "n3", index: 0 }]] },
        n3: { main: [[{ node: "n4", index: 0 }]] },
        n4: { main: [[{ node: "n5", index: 0 }], []] },
        n5: { main: [[{ node: "n6", index: 0 }]] },
      },
    },
  },
  {
    id: "li_view_profiles",
    platform: "linkedin",
    category: "engagement",
    label: "View Profiles",
    description: "Visit a list of profiles to surface as 'who's viewed your profile' in their feed (warming).",
    launchUrl: "https://www.linkedin.com",
    moduleMap: {
      nodes: [
        { id: "n1", type: "trigger.manual",        name: "User clicks View Profiles" },
        { id: "n2", type: "db.query",              name: "Load target profile list" },
        { id: "n3", type: "logic.loop",            name: "For each profile" },
        { id: "n4", type: "logic.rate_limit",      name: "Daily view cap?" },
        { id: "n5", type: "browser.view_profile",  name: "Visit profile page" },
        { id: "n6", type: "db.record_event",       name: "Log profile view" },
      ],
      connections: {
        n1: { main: [[{ node: "n2", index: 0 }]] },
        n2: { main: [[{ node: "n3", index: 0 }]] },
        n3: { main: [[{ node: "n4", index: 0 }]] },
        n4: { main: [[{ node: "n5", index: 0 }]] },
        n5: { main: [[{ node: "n6", index: 0 }]] },
      },
    },
  },
  {
    id: "li_accept_invites",
    platform: "linkedin",
    category: "manage",
    label: "Accept Invites",
    description: "Auto-accept pending connection requests, optionally filtered by sender profile/role.",
    launchUrl: "https://www.linkedin.com/mynetwork/invitation-manager/received/",
    moduleMap: {
      nodes: [
        { id: "n1", type: "trigger.manual",          name: "User clicks Accept Invites" },
        { id: "n2", type: "browser.scan_feed",       name: "Load pending invitations" },
        { id: "n3", type: "logic.loop",              name: "For each invite" },
        { id: "n4", type: "ai.match_icp",            name: "AI: relevant sender?" },
        { id: "n5", type: "logic.if",                name: "Above threshold?" },
        { id: "n6", type: "browser.send_connect",    name: "Accept invite" },
        { id: "n7", type: "db.upsert_contact",       name: "Upsert into shared_contacts" },
        { id: "n8", type: "db.record_event",         name: "Log accept" },
      ],
      connections: {
        n1: { main: [[{ node: "n2", index: 0 }]] },
        n2: { main: [[{ node: "n3", index: 0 }]] },
        n3: { main: [[{ node: "n4", index: 0 }]] },
        n4: { main: [[{ node: "n5", index: 0 }]] },
        n5: { main: [[{ node: "n6", index: 0 }], []] },
        n6: { main: [[{ node: "n7", index: 0 }]] },
        n7: { main: [[{ node: "n8", index: 0 }]] },
      },
    },
  },
  {
    id: "li_accept_and_dm",
    platform: "linkedin",
    category: "manage",
    label: "Accept & Message",
    description: "Accept all pending connection requests and send each new connection a personalized DM (custom message per run).",
    launchUrl: "https://www.linkedin.com/mynetwork/invitation-manager/received/",
    moduleMap: {
      nodes: [
        { id: "n1", type: "trigger.manual",       name: "User enters DM template" },
        { id: "n2", type: "browser.scan_feed",    name: "Load pending invitations" },
        { id: "n3", type: "logic.loop",           name: "For each invitation" },
        { id: "n4", type: "browser.send_connect", name: "Accept invitation" },
        { id: "n5", type: "browser.send_message", name: "Send personalized DM" },
        { id: "n6", type: "db.upsert_contact",    name: "Upsert into shared_contacts" },
        { id: "n7", type: "db.record_event",      name: "Log accept + DM" },
      ],
      connections: {
        n1: { main: [[{ node: "n2", index: 0 }]] },
        n2: { main: [[{ node: "n3", index: 0 }]] },
        n3: { main: [[{ node: "n4", index: 0 }]] },
        n4: { main: [[{ node: "n5", index: 0 }]] },
        n5: { main: [[{ node: "n6", index: 0 }]] },
        n6: { main: [[{ node: "n7", index: 0 }]] },
      },
    },
  },
  {
    id: "li_smart_disconnect",
    platform: "linkedin",
    category: "manage",
    label: "Clean Up Connections",
    description: "Review your connections, score them by recent engagement / role fit, and remove low-value ones.",
    launchUrl: "https://www.linkedin.com/mynetwork/invite-connect/connections/",
    moduleMap: {
      nodes: [
        { id: "n1", type: "trigger.manual",          name: "User clicks Clean Up Connections" },
        { id: "n2", type: "browser.scrape_followers", name: "List your 1st-degree connections" },
        { id: "n3", type: "logic.loop",              name: "For each connection" },
        { id: "n4", type: "browser.view_profile",    name: "Fetch profile metadata" },
        { id: "n5", type: "ai.match_icp",            name: "AI: still relevant?" },
        { id: "n6", type: "logic.if",                name: "Below threshold?" },
        { id: "n7", type: "browser.disconnect",      name: "Remove connection" },
        { id: "n8", type: "db.record_event",   name: "Log to outreach_events" },
      ],
      connections: {
        n1: { main: [[{ node: "n2", index: 0 }]] },
        n2: { main: [[{ node: "n3", index: 0 }]] },
        n3: { main: [[{ node: "n4", index: 0 }]] },
        n4: { main: [[{ node: "n5", index: 0 }]] },
        n5: { main: [[{ node: "n6", index: 0 }]] },
        n6: { main: [[{ node: "n7", index: 0 }], []] },
        n7: { main: [[{ node: "n8", index: 0 }]] },
      },
    },
  },
  {
    id: "li_autopilot",
    platform: "linkedin",
    category: "manage",
    label: "Autopilot",
    description: "Continuous engagement during your active hours — interleaves likes, profile views, and comment replies.",
    launchUrl: "https://www.linkedin.com",
    moduleMap: {
      nodes: [
        { id: "n1", type: "trigger.cron",          name: "Every N min during active hours" },
        { id: "n2", type: "logic.if",              name: "In active-hours window?" },
        { id: "n3", type: "logic.switch",          name: "Pick next action (round-robin)" },
        { id: "n4", type: "browser.like_post",     name: "Like a feed post" },
        { id: "n5", type: "browser.view_profile",  name: "View a profile" },
        { id: "n6", type: "browser.send_connect",  name: "Send a connect request" },
        { id: "n7", type: "logic.rate_limit",      name: "Daily cap reached?" },
        { id: "n8", type: "db.record_event",       name: "Log action" },
      ],
      connections: {
        n1: { main: [[{ node: "n2", index: 0 }]] },
        n2: { main: [[{ node: "n3", index: 0 }], []] },
        n3: { main: [
          [{ node: "n4", index: 0 }],
          [{ node: "n5", index: 0 }],
          [{ node: "n6", index: 0 }],
        ] },
        n4: { main: [[{ node: "n7", index: 0 }]] },
        n5: { main: [[{ node: "n7", index: 0 }]] },
        n6: { main: [[{ node: "n7", index: 0 }]] },
        n7: { main: [[{ node: "n8", index: 0 }]] },
      },
    },
  },

  // ─────────────────────────────────────────────────────────────────────
  // TWITTER / X (15)
  // ─────────────────────────────────────────────────────────────────────
  {
    id: "x_competitor_siphon",
    platform: "twitter",
    category: "intelligence",
    label: "Competitor Siphon",
    description: "Extract followers of a competitor's X account and follow / DM them.",
    launchUrl: "https://x.com",
    runFromHere: {
      actionId: "x_competitor_siphon",
      url: "https://x.com",
      fields: [
        { id: "cfg-target", label: "Target account", type: "text", placeholder: "@competitor" },
        { id: "cfg-depth", label: "Depth", type: "select", default: "medium", options: [["light","Light"],["medium","Medium"],["heavy","Heavy"]] },
        { id: "cfg-max", label: "Max followers to engage", type: "number", default: 15, min: 5, max: 50 }
      ],
    },
    moduleMap: {
      nodes: [
        { id: "n1", type: "trigger.manual",            name: "User enters competitor handle" },
        { id: "n2", type: "browser.parse_post_url",    name: "Parse target handle" },
        { id: "n3", type: "browser.scrape_followers",  name: "Scrape competitor's followers" },
        { id: "n4", type: "logic.loop",                name: "For each follower" },
        { id: "n5", type: "ai.match_icp",              name: "AI: matches your ICP?" },
        { id: "n6", type: "logic.if",                  name: "Above threshold?" },
        { id: "n7", type: "browser.follow_user",       name: "Follow them" },
        { id: "n8", type: "db.upsert_contact",         name: "Save to CRM" },
        { id: "n9", type: "db.record_event",           name: "Log follow" },
      ],
      connections: {
        n1: { main: [[{ node: "n2", index: 0 }]] },
        n2: { main: [[{ node: "n3", index: 0 }]] },
        n3: { main: [[{ node: "n4", index: 0 }]] },
        n4: { main: [[{ node: "n5", index: 0 }]] },
        n5: { main: [[{ node: "n6", index: 0 }]] },
        n6: { main: [[{ node: "n7", index: 0 }], []] },
        n7: { main: [[{ node: "n8", index: 0 }]] },
        n8: { main: [[{ node: "n9", index: 0 }]] },
      },
    },
  },
  {
    id: "x_audience_overlap",
    platform: "twitter",
    category: "intelligence",
    label: "Audience Overlap",
    description: "Find users who follow MULTIPLE target accounts — the highest-intent prospects in a niche.",
    launchUrl: "https://x.com",
    runFromHere: {
      actionId: "x_audience_overlap",
      url: "https://x.com",
      fields: [
        { id: "cfg-targets", label: "Competitor accounts (2-3, comma-separated)", type: "text", placeholder: "@a, @b, @c" },
        { id: "cfg-max", label: "Max followers to scan per account", type: "number", default: 50, min: 20, max: 200 }
      ],
    },
    moduleMap: {
      nodes: [
        { id: "n1", type: "trigger.manual",            name: "User enters 2+ target handles" },
        { id: "n2", type: "logic.loop",                name: "For each target" },
        { id: "n3", type: "browser.scrape_followers",  name: "Scrape that target's followers" },
        { id: "n4", type: "db.upsert_contact",         name: "Upsert into shared_contacts" },
        { id: "n5", type: "db.query",                  name: "Query: who appears in 2+ lists?" },
        { id: "n6", type: "ai.match_icp",              name: "AI: rank by ICP fit" },
        { id: "n7", type: "notify.telegram_user",      name: "Notify with top overlap matches" },
      ],
      connections: {
        n1: { main: [[{ node: "n2", index: 0 }]] },
        n2: { main: [[{ node: "n3", index: 0 }]] },
        n3: { main: [[{ node: "n4", index: 0 }]] },
        n4: { main: [[{ node: "n5", index: 0 }]] },
        n5: { main: [[{ node: "n6", index: 0 }]] },
        n6: { main: [[{ node: "n7", index: 0 }]] },
      },
    },
  },
  {
    id: "x_engagement_campaign",
    platform: "twitter",
    category: "intelligence",
    label: "Engagement Campaign",
    description: "Systematically like + reply + retweet ONE target account's content to land in their notifications.",
    launchUrl: "https://x.com",
    runFromHere: {
      actionId: "x_engagement_campaign",
      url: "https://x.com",
      fields: [
        { id: "cfg-target", label: "Target account", type: "text", placeholder: "@influencer" },
        { id: "cfg-depth", label: "Depth", type: "select", default: "medium", options: [["light","Light"],["medium","Medium"],["heavy","Heavy"]] }
      ],
    },
    moduleMap: {
      nodes: [
        { id: "n1", type: "trigger.manual",       name: "User clicks Engagement Campaign" },
        { id: "n2", type: "browser.parse_post_url", name: "Parse target account handle" },
        { id: "n3", type: "scrape.twitter_search", name: "Fetch target's recent posts" },
        { id: "n4", type: "logic.loop",           name: "For each post" },
        { id: "n5", type: "browser.like_post",    name: "Like" },
        { id: "n6", type: "browser.retweet",      name: "Retweet" },
        { id: "n7", type: "ai.generate_reply",    name: "AI-draft reply" },
        { id: "n8", type: "browser.reply",        name: "Post reply" },
        { id: "n9", type: "db.record_event", name: "Log engagement" },
      ],
      connections: {
        n1: { main: [[{ node: "n2", index: 0 }]] },
        n2: { main: [[{ node: "n3", index: 0 }]] },
        n3: { main: [[{ node: "n4", index: 0 }]] },
        n4: { main: [[{ node: "n5", index: 0 }]] },
        n5: { main: [[{ node: "n6", index: 0 }]] },
        n6: { main: [[{ node: "n7", index: 0 }]] },
        n7: { main: [[{ node: "n8", index: 0 }]] },
        n8: { main: [[{ node: "n9", index: 0 }]] },
      },
    },
  },
  {
    id: "x_like_feed",
    platform: "twitter",
    category: "engagement",
    label: "Engage Feed",
    description: "Like posts from your X home timeline. Skips your own posts and posts you've already engaged with.",
    launchUrl: "https://x.com/home",
    // Run-from-here (background-tab adapter). When present the dashboard shows a
    // "Configure & run →" button that fires `swAction`, and background.js runs
    // the action in a hidden x.com worker tab — no need to be on x.com.
    // `fields[].id` must match the cfg-* id the panel action reads (see
    // content-twitter.js ACTION_CONFIGS["like-feed"], which reads cfg-count).
    runFromHere: {
      actionId: "x_like_feed",
      url: "https://x.com/home",
      fields: [
        { id: "cfg-count", label: "Posts to like", type: "number", default: 20, min: 1, max: 100 }
      ],
    },
    moduleMap: {
      nodes: [
        { id: "n1", type: "trigger.manual",       name: "User clicks Engage Feed" },
        { id: "n2", type: "browser.scan_feed",    name: "Scan home timeline" },
        { id: "n3", type: "logic.loop",           name: "For each post" },
        { id: "n4", type: "logic.if",             name: "Already liked / own post?" },
        { id: "n5", type: "browser.like_post",    name: "Like the post" },
        { id: "n6", type: "db.record_event", name: "Log like" },
      ],
      connections: {
        n1: { main: [[{ node: "n2", index: 0 }]] },
        n2: { main: [[{ node: "n3", index: 0 }]] },
        n3: { main: [[{ node: "n4", index: 0 }]] },
        n4: { main: [[], [{ node: "n5", index: 0 }]] },
        n5: { main: [[{ node: "n6", index: 0 }]] },
      },
    },
  },
  {
    id: "x_reply_feed",
    platform: "twitter",
    category: "engagement",
    label: "Reply to Posts",
    description: "AI-draft and post replies to feed posts. Optionally gates by relevance score.",
    launchUrl: "https://x.com/home",
    runFromHere: {
      actionId: "x_reply_feed",
      url: "https://x.com/home",
      fields: [
        { id: "cfg-text", label: "Reply text (empty = AI-generated)", type: "textarea", default: "", placeholder: "AI-generated if empty", optional: true },
        { id: "cfg-count", label: "Posts to reply to", type: "number", default: 5, min: 1, max: 20 }
      ],
    },
    moduleMap: {
      nodes: [
        { id: "n1", type: "trigger.manual",       name: "User clicks Reply to Posts" },
        { id: "n2", type: "browser.scan_feed",    name: "Scan home timeline" },
        { id: "n3", type: "logic.loop",           name: "For each post" },
        { id: "n4", type: "ai.classify_signal",   name: "AI: relevance score" },
        { id: "n5", type: "logic.if",             name: "Above threshold?" },
        { id: "n6", type: "ai.generate_reply",    name: "AI-draft reply" },
        { id: "n7", type: "browser.reply",        name: "Post reply" },
        { id: "n8", type: "db.record_event",      name: "Log reply" },
      ],
      connections: {
        n1: { main: [[{ node: "n2", index: 0 }]] },
        n2: { main: [[{ node: "n3", index: 0 }]] },
        n3: { main: [[{ node: "n4", index: 0 }]] },
        n4: { main: [[{ node: "n5", index: 0 }]] },
        n5: { main: [[{ node: "n6", index: 0 }], []] },
        n6: { main: [[{ node: "n7", index: 0 }]] },
        n7: { main: [[{ node: "n8", index: 0 }]] },
      },
    },
  },
  {
    id: "x_retweet",
    platform: "twitter",
    category: "engagement",
    label: "Retweet Posts",
    description: "Retweet posts from your feed (keyword-filtered or AI-selected for topic fit).",
    launchUrl: "https://x.com/home",
    runFromHere: {
      actionId: "x_retweet",
      url: "https://x.com/home",
      fields: [
        { id: "cfg-count", label: "Posts to retweet", type: "number", default: 5, min: 1, max: 20 }
      ],
    },
    moduleMap: {
      nodes: [
        { id: "n1", type: "trigger.manual",        name: "User clicks Retweet Posts" },
        { id: "n2", type: "browser.scan_feed",     name: "Scan home timeline" },
        { id: "n3", type: "logic.loop",            name: "For each post" },
        { id: "n4", type: "ai.classify_signal",    name: "AI: topic fit" },
        { id: "n5", type: "logic.if",              name: "Above threshold?" },
        { id: "n6", type: "browser.retweet",       name: "Retweet" },
        { id: "n7", type: "db.record_event",       name: "Log retweet" },
      ],
      connections: {
        n1: { main: [[{ node: "n2", index: 0 }]] },
        n2: { main: [[{ node: "n3", index: 0 }]] },
        n3: { main: [[{ node: "n4", index: 0 }]] },
        n4: { main: [[{ node: "n5", index: 0 }]] },
        n5: { main: [[{ node: "n6", index: 0 }], []] },
        n6: { main: [[{ node: "n7", index: 0 }]] },
      },
    },
  },
  {
    id: "x_engage_hashtag",
    platform: "twitter",
    category: "engagement",
    label: "Engage Hashtag",
    description: "Like and reply to recent posts under a specific hashtag (#defi, #web3, etc.).",
    launchUrl: "https://x.com/explore",
    // Run-from-here — see x_like_feed note. cfg-hashtag matches the field the
    // panel action ACTION_CONFIGS["engage-hashtag"] reads.
    runFromHere: {
      actionId: "x_engage_hashtag",
      url: "https://x.com/explore",
      fields: [
        { id: "cfg-hashtag", label: "Hashtag", type: "text", default: "", placeholder: "#web3" }
      ],
    },
    moduleMap: {
      nodes: [
        { id: "n1", type: "trigger.manual",         name: "User enters hashtag" },
        { id: "n2", type: "scrape.twitter_search",  name: "Search posts under hashtag" },
        { id: "n3", type: "logic.loop",             name: "For each post" },
        { id: "n4", type: "browser.like_post",      name: "Like the post" },
        { id: "n5", type: "ai.generate_reply",      name: "AI-draft reply" },
        { id: "n6", type: "browser.reply",          name: "Post reply" },
        { id: "n7", type: "db.record_event",        name: "Log engagement" },
      ],
      connections: {
        n1: { main: [[{ node: "n2", index: 0 }]] },
        n2: { main: [[{ node: "n3", index: 0 }]] },
        n3: { main: [[{ node: "n4", index: 0 }]] },
        n4: { main: [[{ node: "n5", index: 0 }]] },
        n5: { main: [[{ node: "n6", index: 0 }]] },
        n6: { main: [[{ node: "n7", index: 0 }]] },
      },
    },
  },
  {
    id: "x_engage_feed_ai",
    platform: "twitter",
    category: "engagement",
    label: "Auto-Engage (AI)",
    description: "AI-driven mix of likes, replies, and retweets across your feed — natural-looking activity.",
    launchUrl: "https://x.com/home",
    runFromHere: {
      actionId: "x_engage_feed_ai",
      url: "https://x.com/home",
      fields: [],
    },
    moduleMap: {
      nodes: [
        { id: "n1", type: "trigger.manual",       name: "User clicks Auto-Engage (AI)" },
        { id: "n2", type: "browser.scan_feed",    name: "Scan home timeline" },
        { id: "n3", type: "logic.loop",           name: "For each post" },
        { id: "n4", type: "ai.classify_signal",   name: "AI: pick action (like/reply/RT/skip)" },
        { id: "n5", type: "logic.switch",         name: "Route by chosen action" },
        { id: "n6", type: "browser.like_post",    name: "Like" },
        { id: "n7", type: "browser.retweet",      name: "Retweet" },
        { id: "n8", type: "ai.generate_reply",    name: "AI-draft reply" },
        { id: "n9", type: "browser.reply",        name: "Post reply" },
        { id: "n10", type: "db.record_event",     name: "Log action" },
      ],
      connections: {
        n1: { main: [[{ node: "n2", index: 0 }]] },
        n2: { main: [[{ node: "n3", index: 0 }]] },
        n3: { main: [[{ node: "n4", index: 0 }]] },
        n4: { main: [[{ node: "n5", index: 0 }]] },
        n5: { main: [
          [{ node: "n6", index: 0 }],
          [{ node: "n7", index: 0 }],
          [{ node: "n8", index: 0 }],
        ] },
        n6: { main: [[{ node: "n10", index: 0 }]] },
        n7: { main: [[{ node: "n10", index: 0 }]] },
        n8: { main: [[{ node: "n9", index: 0 }]] },
        n9: { main: [[{ node: "n10", index: 0 }]] },
      },
    },
  },
  {
    id: "x_follow_users",
    platform: "twitter",
    category: "grow",
    label: "Follow Users",
    description: "Follow a list of usernames you paste in.",
    launchUrl: "https://x.com",
    runFromHere: {
      actionId: "x_follow_users",
      url: "https://x.com",
      fields: [
        { id: "cfg-targets", label: "Usernames to follow (comma-separated)", type: "textarea", placeholder: "@user1, @user2, @user3" }
      ],
    },
    moduleMap: {
      nodes: [
        { id: "n1", type: "trigger.manual",       name: "User pastes handle list" },
        { id: "n2", type: "logic.loop",           name: "For each handle" },
        { id: "n3", type: "logic.rate_limit",     name: "Daily follow cap?" },
        { id: "n4", type: "browser.follow_user",  name: "Follow user" },
        { id: "n5", type: "db.record_event",      name: "Log follow" },
      ],
      connections: {
        n1: { main: [[{ node: "n2", index: 0 }]] },
        n2: { main: [[{ node: "n3", index: 0 }]] },
        n3: { main: [[{ node: "n4", index: 0 }]] },
        n4: { main: [[{ node: "n5", index: 0 }]] },
      },
    },
  },
  {
    id: "x_follower_sniper",
    platform: "twitter",
    category: "grow",
    label: "Follower Sniper",
    description: "Follow people who follow a specific target account (steal their audience one tier deep).",
    launchUrl: "https://x.com",
    runFromHere: {
      actionId: "x_follower_sniper",
      url: "https://x.com",
      fields: [
        { id: "cfg-target", label: "Target account (steal their followers)", type: "text", placeholder: "@competitor" },
        { id: "cfg-count", label: "Max follows", type: "number", default: 10, min: 1, max: 50 }
      ],
    },
    moduleMap: {
      nodes: [
        { id: "n1", type: "trigger.manual",            name: "User clicks Follower Sniper" },
        { id: "n2", type: "browser.parse_post_url",    name: "Parse target account handle" },
        { id: "n3", type: "browser.scrape_followers",  name: "Scrape target's followers" },
        { id: "n4", type: "logic.loop",                name: "For each follower" },
        { id: "n5", type: "logic.if",                  name: "Already following?" },
        { id: "n6", type: "browser.follow_user",       name: "Follow them" },
        { id: "n7", type: "db.record_event",     name: "Log follow" },
      ],
      connections: {
        n1: { main: [[{ node: "n2", index: 0 }]] },
        n2: { main: [[{ node: "n3", index: 0 }]] },
        n3: { main: [[{ node: "n4", index: 0 }]] },
        n4: { main: [[{ node: "n5", index: 0 }]] },
        n5: { main: [[], [{ node: "n6", index: 0 }]] },
        n6: { main: [[{ node: "n7", index: 0 }]] },
      },
    },
  },
  {
    id: "x_retweet_campaign",
    platform: "twitter",
    category: "grow",
    label: "Retweet Campaign",
    description: "On a schedule, retweet the latest posts from a curated list of accounts.",
    launchUrl: "https://x.com",
    runFromHere: {
      actionId: "x_retweet_campaign",
      url: "https://x.com",
      fields: [
        { id: "cfg-target", label: "Target account to retweet", type: "text", placeholder: "@account" },
        { id: "cfg-count", label: "Tweets to retweet", type: "number", default: 5, min: 1, max: 20 }
      ],
    },
    moduleMap: {
      nodes: [
        { id: "n1", type: "trigger.cron",           name: "On schedule (e.g. every 4h)" },
        { id: "n2", type: "db.query",               name: "Load curated handle list" },
        { id: "n3", type: "logic.loop",             name: "For each handle" },
        { id: "n4", type: "scrape.twitter_search",  name: "Fetch latest post(s)" },
        { id: "n5", type: "logic.if",               name: "Already retweeted?" },
        { id: "n6", type: "browser.retweet",        name: "Retweet" },
        { id: "n7", type: "db.record_event",        name: "Log retweet" },
      ],
      connections: {
        n1: { main: [[{ node: "n2", index: 0 }]] },
        n2: { main: [[{ node: "n3", index: 0 }]] },
        n3: { main: [[{ node: "n4", index: 0 }]] },
        n4: { main: [[{ node: "n5", index: 0 }]] },
        n5: { main: [[], [{ node: "n6", index: 0 }]] },
        n6: { main: [[{ node: "n7", index: 0 }]] },
      },
    },
  },
  {
    id: "x_post_tweet",
    platform: "twitter",
    category: "grow",
    label: "Post Tweet",
    description: "Compose and publish a tweet (with optional thread support).",
    launchUrl: "https://x.com/compose/tweet",
    runFromHere: {
      actionId: "x_post_tweet",
      url: "https://x.com/home",
      fields: [
        { id: "cfg-text", label: "Tweet text", type: "textarea", placeholder: "What's happening?" }
      ],
    },
    moduleMap: {
      nodes: [
        { id: "n1", type: "trigger.manual",         name: "User clicks Post Tweet" },
        { id: "n2", type: "ai.generate_reply",      name: "(Optional) AI-draft tweet text" },
        { id: "n3", type: "browser.compose_post",   name: "Open composer + paste text" },
        { id: "n4", type: "logic.if",               name: "Thread? (multiple parts)" },
        { id: "n5", type: "logic.loop",             name: "For each thread part" },
        { id: "n6", type: "browser.compose_post",   name: "Reply to previous part" },
        { id: "n7", type: "db.record_event",        name: "Log post" },
      ],
      connections: {
        n1: { main: [[{ node: "n2", index: 0 }]] },
        n2: { main: [[{ node: "n3", index: 0 }]] },
        n3: { main: [[{ node: "n4", index: 0 }]] },
        n4: { main: [[{ node: "n5", index: 0 }], [{ node: "n7", index: 0 }]] },
        n5: { main: [[{ node: "n6", index: 0 }]] },
        n6: { main: [[{ node: "n7", index: 0 }]] },
      },
    },
  },
  {
    id: "x_quote_tweet",
    platform: "twitter",
    category: "grow",
    label: "Quote Tweet",
    description: "Quote a specific tweet URL with your commentary.",
    launchUrl: "https://x.com/compose/tweet",
    runFromHere: {
      actionId: "x_quote_tweet",
      url: "https://x.com/home",
      fields: [
        { id: "cfg-tweet-id", label: "Tweet URL or ID", type: "text", placeholder: "https://x.com/user/status/123… or the ID" },
        { id: "cfg-text", label: "Your comment", type: "textarea", placeholder: "Great thread!" }
      ],
    },
    moduleMap: {
      nodes: [
        { id: "n1", type: "trigger.manual",          name: "User pastes tweet URL" },
        { id: "n2", type: "browser.parse_post_url",  name: "Parse + validate tweet URL" },
        { id: "n3", type: "ai.generate_reply",       name: "(Optional) AI-draft commentary" },
        { id: "n4", type: "browser.compose_post",    name: "Open quote composer + post" },
        { id: "n5", type: "db.record_event",         name: "Log quote tweet" },
      ],
      connections: {
        n1: { main: [[{ node: "n2", index: 0 }]] },
        n2: { main: [[{ node: "n3", index: 0 }]] },
        n3: { main: [[{ node: "n4", index: 0 }]] },
        n4: { main: [[{ node: "n5", index: 0 }]] },
      },
    },
  },
  {
    id: "x_smart_unfollow",
    platform: "twitter",
    category: "manage",
    label: "Clean Up Following",
    description: "Unfollow accounts that don't follow you back, weighted by aging + recent engagement.",
    launchUrl: "https://x.com",
    runFromHere: {
      actionId: "x_smart_unfollow",
      url: "https://x.com",
      fields: [
        { id: "cfg-keyword", label: "Keep accounts matching keyword", type: "text", placeholder: "crypto, web3, defi" },
        { id: "cfg-max", label: "Max to scan", type: "number", default: 50, min: 10, max: 200 },
        { id: "cfg-preview", label: "Preview before unfollowing", type: "boolean", default: true }
      ],
    },
    moduleMap: {
      nodes: [
        { id: "n1", type: "trigger.manual",         name: "User clicks Clean Up Following" },
        { id: "n2", type: "browser.scrape_followers", name: "List who you follow" },
        { id: "n3", type: "logic.loop",             name: "For each followed user" },
        { id: "n4", type: "logic.if",               name: "They follow back?" },
        { id: "n5", type: "browser.unfollow_user",  name: "Unfollow" },
        { id: "n6", type: "db.record_event",  name: "Log unfollow" },
      ],
      connections: {
        n1: { main: [[{ node: "n2", index: 0 }]] },
        n2: { main: [[{ node: "n3", index: 0 }]] },
        n3: { main: [[{ node: "n4", index: 0 }]] },
        n4: { main: [[], [{ node: "n5", index: 0 }]] },
        n5: { main: [[{ node: "n6", index: 0 }]] },
      },
    },
  },
  {
    id: "x_autopilot",
    platform: "twitter",
    category: "manage",
    label: "Autopilot",
    description: "Continuous automated engagement during your active hours.",
    launchUrl: "https://x.com",
    moduleMap: {
      nodes: [
        { id: "n1", type: "trigger.cron",          name: "Every N min during active hours" },
        { id: "n2", type: "logic.if",              name: "In active-hours window?" },
        { id: "n3", type: "logic.switch",          name: "Pick next action (round-robin)" },
        { id: "n4", type: "browser.like_post",     name: "Like a feed post" },
        { id: "n5", type: "browser.retweet",       name: "Retweet a feed post" },
        { id: "n6", type: "browser.reply",         name: "Reply to a feed post" },
        { id: "n7", type: "browser.follow_user",   name: "Follow a suggested user" },
        { id: "n8", type: "logic.rate_limit",      name: "Daily cap reached?" },
        { id: "n9", type: "db.record_event",       name: "Log action" },
      ],
      connections: {
        n1: { main: [[{ node: "n2", index: 0 }]] },
        n2: { main: [[{ node: "n3", index: 0 }], []] },
        n3: { main: [
          [{ node: "n4", index: 0 }],
          [{ node: "n5", index: 0 }],
          [{ node: "n6", index: 0 }],
          [{ node: "n7", index: 0 }],
        ] },
        n4: { main: [[{ node: "n8", index: 0 }]] },
        n5: { main: [[{ node: "n8", index: 0 }]] },
        n6: { main: [[{ node: "n8", index: 0 }]] },
        n7: { main: [[{ node: "n8", index: 0 }]] },
        n8: { main: [[{ node: "n9", index: 0 }]] },
      },
    },
  },

  // ─────────────────────────────────────────────────────────────────────
  // TELEGRAM (web) (4)
  // ─────────────────────────────────────────────────────────────────────
  {
    id: "tg_group_scraper",
    platform: "telegram",
    category: "intelligence",
    label: "Group Scraper",
    description: "Scrape members from a Telegram group and sync them into shared_contacts (CRM).",
    launchUrl: "https://web.telegram.org",
    moduleMap: {
      nodes: [
        { id: "n1", type: "trigger.manual",          name: "User clicks Group Scraper" },
        { id: "n2", type: "browser.parse_post_url",  name: "Parse target group URL/handle" },
        { id: "n3", type: "browser.scrape_followers", name: "Scrape member list via MTProto" },
        { id: "n4", type: "logic.loop",              name: "For each member" },
        { id: "n5", type: "db.upsert_contact",       name: "Upsert into shared_contacts" },
        { id: "n6", type: "db.record_event",   name: "Log scrape" },
      ],
      connections: {
        n1: { main: [[{ node: "n2", index: 0 }]] },
        n2: { main: [[{ node: "n3", index: 0 }]] },
        n3: { main: [[{ node: "n4", index: 0 }]] },
        n4: { main: [[{ node: "n5", index: 0 }]] },
        n5: { main: [[{ node: "n6", index: 0 }]] },
      },
    },
  },
  {
    id: "tg_group_analytics",
    platform: "telegram",
    category: "intelligence",
    label: "Group Analytics",
    description: "View scraped groups, member counts, active talkers, and overlap between groups.",
    launchUrl: "https://web.telegram.org",
    moduleMap: {
      nodes: [
        { id: "n1", type: "trigger.manual",         name: "User opens Group Analytics" },
        { id: "n2", type: "db.query",               name: "Load scraped groups + members" },
        { id: "n3", type: "logic.loop",             name: "For each group" },
        { id: "n4", type: "ai.classify_signal",     name: "Compute active-talker / overlap stats" },
        { id: "n5", type: "db.upsert_contact",      name: "Cache group analytics row" },
        { id: "n6", type: "notify.telegram_user",   name: "Render dashboard" },
      ],
      connections: {
        n1: { main: [[{ node: "n2", index: 0 }]] },
        n2: { main: [[{ node: "n3", index: 0 }]] },
        n3: { main: [[{ node: "n4", index: 0 }]] },
        n4: { main: [[{ node: "n5", index: 0 }]] },
        n5: { main: [[{ node: "n6", index: 0 }]] },
      },
    },
  },
  {
    id: "tg_bulk_dm",
    platform: "telegram",
    category: "engagement",
    label: "Bulk DM",
    description: "Send DMs to a list of Telegram users via the account pool with rate limiting + spacing.",
    launchUrl: "https://web.telegram.org",
    moduleMap: {
      nodes: [
        { id: "n1", type: "trigger.manual",        name: "User clicks Bulk DM" },
        { id: "n2", type: "db.query",              name: "Load DM target list" },
        { id: "n3", type: "logic.loop",            name: "For each target" },
        { id: "n4", type: "logic.rate_limit",      name: "Per-account daily cap" },
        { id: "n5", type: "browser.send_message",  name: "Send DM via MTProto" },
        { id: "n6", type: "db.record_event", name: "Log DM" },
      ],
      connections: {
        n1: { main: [[{ node: "n2", index: 0 }]] },
        n2: { main: [[{ node: "n3", index: 0 }]] },
        n3: { main: [[{ node: "n4", index: 0 }]] },
        n4: { main: [[{ node: "n5", index: 0 }]] },
        n5: { main: [[{ node: "n6", index: 0 }]] },
      },
    },
  },
  {
    id: "tg_account_pool",
    platform: "telegram",
    category: "manage",
    label: "Account Pool",
    description: "View Telegram account health, daily action counts, cooldown timers, and pause/resume per account.",
    launchUrl: "https://web.telegram.org",
    moduleMap: {
      nodes: [
        { id: "n1", type: "trigger.manual",        name: "User opens Account Pool" },
        { id: "n2", type: "db.query",              name: "Load all Telegram accounts" },
        { id: "n3", type: "logic.loop",            name: "For each account" },
        { id: "n4", type: "ai.classify_signal",    name: "Compute health score" },
        { id: "n5", type: "logic.if",              name: "In cooldown / flagged?" },
        { id: "n6", type: "notify.telegram_user",  name: "Mark paused + alert operator" },
        { id: "n7", type: "db.record_event",       name: "Render pool dashboard row" },
      ],
      connections: {
        n1: { main: [[{ node: "n2", index: 0 }]] },
        n2: { main: [[{ node: "n3", index: 0 }]] },
        n3: { main: [[{ node: "n4", index: 0 }]] },
        n4: { main: [[{ node: "n5", index: 0 }]] },
        n5: { main: [[{ node: "n6", index: 0 }], [{ node: "n7", index: 0 }]] },
        n6: { main: [[{ node: "n7", index: 0 }]] },
      },
    },
  },
];

// Convenience grouping for the dashboard. Returns a Map<platform, action[]>.
window.groupPlatformActions = function () {
  const map = new Map();
  for (const a of window.PLATFORM_ACTIONS) {
    if (!map.has(a.platform)) map.set(a.platform, []);
    map.get(a.platform).push(a);
  }
  return map;
};

window.findPlatformAction = function (id) {
  return window.PLATFORM_ACTIONS.find((a) => a.id === id) || null;
};
