{"version":3,"file":"clawnx.mjs","names":[],"sources":["../../../src/tools/clawnx.ts"],"sourcesContent":["/**\n * ClawnX Tool — X/Twitter integration via @clawnch/clawnx\n *\n * 45+ actions covering content posting, engagement, social graph,\n * timelines, DMs, lists, streaming, and action chaining.\n *\n * Env vars: X_API_KEY, X_API_SECRET, X_ACCESS_TOKEN,\n *           X_ACCESS_TOKEN_SECRET, X_BEARER_TOKEN\n */\n\nimport { Type } from '@sinclair/typebox';\nimport { stringEnum, jsonResult, errorResult, readStringParam, readNumberParam } from '../lib/tool-helpers.js';\nimport { checkToolConfig } from '../services/tool-config-service.js';\n\nconst ACTIONS = [\n  // Content\n  'post_tweet', 'post_thread', 'post_with_media', 'upload_media',\n  'delete_tweet', 'get_tweet', 'search',\n  // Engagement\n  'like', 'unlike', 'retweet', 'unretweet',\n  'bookmark', 'unbookmark', 'list_bookmarks', 'list_likes',\n  'liking_users', 'retweeted_by', 'quote_tweets',\n  // Social\n  'follow', 'unfollow', 'list_followers', 'list_following',\n  'block', 'unblock', 'mute', 'unmute',\n  'list_blocked', 'list_muted',\n  'get_user', 'search_users', 'lookup_users',\n  // Timelines\n  'get_timeline', 'home_timeline', 'get_mentions',\n  'get_my_profile', 'get_tweet_metrics',\n  // DMs\n  'send_dm', 'send_dm_to_conversation', 'list_dms', 'get_dm_conversation',\n  // Threads\n  'get_conversation',\n  // Lists\n  'create_list', 'delete_list', 'get_list', 'get_user_lists',\n  'add_list_member', 'remove_list_member', 'list_members', 'list_tweets',\n  // Streaming\n  'stream_start', 'stream_stop', 'stream_rules_set', 'stream_rules_get',\n  // Orchestration\n  'action_chain',\n] as const;\n\nconst ClawnXSchema = Type.Object({\n  action: stringEnum(ACTIONS, {\n    description:\n      'Content: post_tweet, post_thread, search, get_tweet. ' +\n      'Engagement: like, retweet, bookmark. Social: follow, block, get_user. ' +\n      'Timelines: get_timeline, home_timeline, get_mentions. ' +\n      'DMs: send_dm, list_dms. Lists: create_list, list_tweets. ' +\n      'Streaming: stream_start/stop/rules. Orchestration: action_chain.',\n  }),\n  text: Type.Optional(Type.String({ description: 'Tweet text or DM message' })),\n  thread: Type.Optional(Type.String({ description: 'JSON array of tweet objects for post_thread' })),\n  query: Type.Optional(Type.String({ description: 'Search query' })),\n  tweet_id: Type.Optional(Type.String({ description: 'Tweet ID' })),\n  username: Type.Optional(Type.String({ description: 'X username (without @)' })),\n  usernames: Type.Optional(Type.String({ description: 'Comma-separated usernames for lookup' })),\n  reply_to: Type.Optional(Type.String({ description: 'Tweet ID to reply to' })),\n  quote: Type.Optional(Type.String({ description: 'Tweet ID to quote' })),\n  media_url: Type.Optional(Type.String({ description: 'URL of media to upload' })),\n  media_type: Type.Optional(Type.String({ description: 'MIME type override for media' })),\n  count: Type.Optional(Type.Number({ description: 'Number of results (max 100, default 20)' })),\n  list_id: Type.Optional(Type.String({ description: 'List ID' })),\n  list_name: Type.Optional(Type.String({ description: 'Name for new list' })),\n  list_description: Type.Optional(Type.String({ description: 'Description for new list' })),\n  list_private: Type.Optional(Type.Boolean({ description: 'Make list private' })),\n  conversation_id: Type.Optional(Type.String({ description: 'DM conversation ID' })),\n  stream_rules: Type.Optional(Type.String({ description: 'JSON array of stream rules [{value, tag?}]' })),\n  stream_duration: Type.Optional(Type.Number({ description: 'Stream duration in seconds (max 300)' })),\n  chain_steps: Type.Optional(Type.String({ description: 'JSON array of action objects for action_chain' })),\n});\n\n// Lazy singleton\nlet _client: any = null;\n\nasync function getClawnX(): Promise<any> {\n  if (_client) return _client;\n\n  // Check required env vars\n  const required = ['X_API_KEY', 'X_API_SECRET', 'X_ACCESS_TOKEN', 'X_ACCESS_TOKEN_SECRET'];\n  const missing = required.filter(k => !process.env[k]);\n  if (missing.length > 0) {\n    throw new Error(`Missing X/Twitter credentials: ${missing.join(', ')}. Set these environment variables.`);\n  }\n\n  const mod = await import('@clawnch/clawnx');\n  _client = new mod.ClawnX();\n  return _client;\n}\n\nexport function createClawnXTool() {\n  return {\n    name: 'clawnx',\n    label: 'ClawnX (X/Twitter)',\n    ownerOnly: true,\n    description:\n      'X/Twitter integration: post tweets, threads, media. Engage with likes, retweets, bookmarks. ' +\n      'Manage followers, lists, DMs. Monitor with streaming. Chain multiple actions together. ' +\n      'Requires X API credentials (X_API_KEY, X_API_SECRET, X_ACCESS_TOKEN, X_ACCESS_TOKEN_SECRET).',\n    parameters: ClawnXSchema,\n    execute: async (_toolCallId: string, args: unknown) => {\n      // Early check: is the tool configured?\n      const notReady = checkToolConfig('clawnx');\n      if (notReady) return notReady;\n\n      const p = args as Record<string, unknown>;\n      const action = readStringParam(p, 'action', { required: true })!;\n\n      try {\n        const x = await getClawnX();\n        const count = Math.min(readNumberParam(p, 'count') ?? 20, 100);\n\n        switch (action) {\n          // ── Content ─────────────────────────────────────────────────\n          case 'post_tweet': {\n            const text = readStringParam(p, 'text', { required: true })!;\n            const result = await x.postTweet({\n              text,\n              replyTo: readStringParam(p, 'reply_to'),\n              quoteTweetId: readStringParam(p, 'quote'),\n            });\n            return jsonResult({ status: 'posted', tweet: result, tweet_id: result?.data?.id });\n          }\n\n          case 'post_thread': {\n            const threadStr = readStringParam(p, 'thread', { required: true })!;\n            const tweets = JSON.parse(threadStr);\n            if (!Array.isArray(tweets) || tweets.length < 2) {\n              return errorResult('Thread must be a JSON array with at least 2 tweet objects [{text: \"...\"}]');\n            }\n            const result = await x.postThread(tweets);\n            return jsonResult({ status: 'posted', thread: result });\n          }\n\n          case 'post_with_media': {\n            const text = readStringParam(p, 'text', { required: true })!;\n            const mediaUrl = readStringParam(p, 'media_url', { required: true })!;\n            const media = await x.uploadMediaFromUrl({\n              url: mediaUrl,\n              mimeType: readStringParam(p, 'media_type'),\n            });\n            const result = await x.postTweet({\n              text,\n              mediaIds: [media.media_id_string],\n              replyTo: readStringParam(p, 'reply_to'),\n              quoteTweetId: readStringParam(p, 'quote'),\n            });\n            return jsonResult({ status: 'posted', tweet: result, media_id: media.media_id_string });\n          }\n\n          case 'upload_media': {\n            const mediaUrl = readStringParam(p, 'media_url', { required: true })!;\n            const result = await x.uploadMediaFromUrl({\n              url: mediaUrl,\n              mimeType: readStringParam(p, 'media_type'),\n            });\n            return jsonResult({ status: 'uploaded', media_id: result.media_id_string });\n          }\n\n          case 'delete_tweet': {\n            const tweetId = readStringParam(p, 'tweet_id', { required: true })!;\n            await x.deleteTweet(tweetId);\n            return jsonResult({ status: 'deleted', tweet_id: tweetId });\n          }\n\n          case 'get_tweet': {\n            const tweetId = readStringParam(p, 'tweet_id', { required: true })!;\n            const result = await x.getTweet(tweetId);\n            return jsonResult(result);\n          }\n\n          case 'search': {\n            const query = readStringParam(p, 'query', { required: true })!;\n            const result = await x.searchTweets({ query, maxResults: Math.min(count, 10) });\n            return jsonResult(result);\n          }\n\n          // ── Engagement ──────────────────────────────────────────────\n          case 'like': {\n            const tweetId = readStringParam(p, 'tweet_id', { required: true })!;\n            await x.likeTweet(tweetId);\n            return jsonResult({ status: 'liked', tweet_id: tweetId });\n          }\n\n          case 'unlike': {\n            const tweetId = readStringParam(p, 'tweet_id', { required: true })!;\n            await x.unlikeTweet(tweetId);\n            return jsonResult({ status: 'unliked', tweet_id: tweetId });\n          }\n\n          case 'retweet': {\n            const tweetId = readStringParam(p, 'tweet_id', { required: true })!;\n            await x.retweet(tweetId);\n            return jsonResult({ status: 'retweeted', tweet_id: tweetId });\n          }\n\n          case 'unretweet': {\n            const tweetId = readStringParam(p, 'tweet_id', { required: true })!;\n            await x.unretweet(tweetId);\n            return jsonResult({ status: 'unretweeted', tweet_id: tweetId });\n          }\n\n          case 'bookmark': {\n            const tweetId = readStringParam(p, 'tweet_id', { required: true })!;\n            await x.bookmarkTweet(tweetId);\n            return jsonResult({ status: 'bookmarked', tweet_id: tweetId });\n          }\n\n          case 'unbookmark': {\n            const tweetId = readStringParam(p, 'tweet_id', { required: true })!;\n            await x.unbookmarkTweet(tweetId);\n            return jsonResult({ status: 'unbookmarked', tweet_id: tweetId });\n          }\n\n          case 'list_bookmarks': {\n            const result = await x.getBookmarks({ maxResults: count });\n            return jsonResult(result);\n          }\n\n          case 'list_likes': {\n            const username = readStringParam(p, 'username', { required: true })!;\n            const result = await x.getLikedTweets(username, { maxResults: count });\n            return jsonResult(result);\n          }\n\n          case 'liking_users': {\n            const tweetId = readStringParam(p, 'tweet_id', { required: true })!;\n            const result = await x.getLikingUsers(tweetId, { maxResults: count });\n            return jsonResult(result);\n          }\n\n          case 'retweeted_by': {\n            const tweetId = readStringParam(p, 'tweet_id', { required: true })!;\n            const result = await x.getRetweetedBy(tweetId, { maxResults: count });\n            return jsonResult(result);\n          }\n\n          case 'quote_tweets': {\n            const tweetId = readStringParam(p, 'tweet_id', { required: true })!;\n            const result = await x.getQuoteTweets(tweetId, { maxResults: count });\n            return jsonResult(result);\n          }\n\n          // ── Social Graph ────────────────────────────────────────────\n          case 'follow': {\n            const username = readStringParam(p, 'username', { required: true })!;\n            await x.followUser(username);\n            return jsonResult({ status: 'followed', username });\n          }\n\n          case 'unfollow': {\n            const username = readStringParam(p, 'username', { required: true })!;\n            await x.unfollowUser(username);\n            return jsonResult({ status: 'unfollowed', username });\n          }\n\n          case 'list_followers': {\n            const username = readStringParam(p, 'username', { required: true })!;\n            const result = await x.getFollowers(username, { maxResults: count });\n            return jsonResult(result);\n          }\n\n          case 'list_following': {\n            const username = readStringParam(p, 'username', { required: true })!;\n            const result = await x.getFollowing(username, { maxResults: count });\n            return jsonResult(result);\n          }\n\n          case 'block': {\n            const username = readStringParam(p, 'username', { required: true })!;\n            await x.blockUser(username);\n            return jsonResult({ status: 'blocked', username });\n          }\n\n          case 'unblock': {\n            const username = readStringParam(p, 'username', { required: true })!;\n            await x.unblockUser(username);\n            return jsonResult({ status: 'unblocked', username });\n          }\n\n          case 'mute': {\n            const username = readStringParam(p, 'username', { required: true })!;\n            await x.muteUser(username);\n            return jsonResult({ status: 'muted', username });\n          }\n\n          case 'unmute': {\n            const username = readStringParam(p, 'username', { required: true })!;\n            await x.unmuteUser(username);\n            return jsonResult({ status: 'unmuted', username });\n          }\n\n          case 'list_blocked': {\n            const result = await x.getBlockedUsers({ maxResults: count });\n            return jsonResult(result);\n          }\n\n          case 'list_muted': {\n            const result = await x.getMutedUsers({ maxResults: count });\n            return jsonResult(result);\n          }\n\n          case 'get_user': {\n            const username = readStringParam(p, 'username', { required: true })!;\n            const result = await x.getUser(username);\n            return jsonResult(result);\n          }\n\n          case 'search_users': {\n            const query = readStringParam(p, 'query', { required: true })!;\n            const result = await x.searchUsers(query, { maxResults: count });\n            return jsonResult(result);\n          }\n\n          case 'lookup_users': {\n            const usernamesStr = readStringParam(p, 'usernames', { required: true })!;\n            const usernames = usernamesStr.split(',').map(u => u.trim());\n            const result = await x.getUsersByUsernames(usernames);\n            return jsonResult(result);\n          }\n\n          // ── Timelines ───────────────────────────────────────────────\n          case 'get_timeline': {\n            const username = readStringParam(p, 'username', { required: true })!;\n            const result = await x.getUserTimeline(username, { maxResults: Math.min(count, 10) });\n            return jsonResult(result);\n          }\n\n          case 'home_timeline': {\n            const result = await x.getHomeTimeline({ maxResults: count });\n            return jsonResult(result);\n          }\n\n          case 'get_mentions': {\n            const result = await x.getMentions({ maxResults: Math.min(count, 10) });\n            return jsonResult(result);\n          }\n\n          case 'get_my_profile': {\n            const result = await x.getMyProfile();\n            return jsonResult(result);\n          }\n\n          case 'get_tweet_metrics': {\n            const tweetId = readStringParam(p, 'tweet_id', { required: true })!;\n            const result = await x.getTweetMetrics(tweetId);\n            return jsonResult(result);\n          }\n\n          // ── DMs ─────────────────────────────────────────────────────\n          case 'send_dm': {\n            const username = readStringParam(p, 'username', { required: true })!;\n            const text = readStringParam(p, 'text', { required: true })!;\n            const result = await x.sendDM(username, { text });\n            return jsonResult({ status: 'sent', result });\n          }\n\n          case 'send_dm_to_conversation': {\n            const convId = readStringParam(p, 'conversation_id', { required: true })!;\n            const text = readStringParam(p, 'text', { required: true })!;\n            const result = await x.sendDMToConversation(convId, { text });\n            return jsonResult({ status: 'sent', result });\n          }\n\n          case 'list_dms': {\n            const result = await x.getDMEvents({ maxResults: count });\n            return jsonResult(result);\n          }\n\n          case 'get_dm_conversation': {\n            const convId = readStringParam(p, 'conversation_id', { required: true })!;\n            const result = await x.getDMConversation(convId, { maxResults: count });\n            return jsonResult(result);\n          }\n\n          // ── Threads / Conversations ─────────────────────────────────\n          case 'get_conversation': {\n            const tweetId = readStringParam(p, 'tweet_id', { required: true })!;\n            const result = await x.getConversation(tweetId, { maxResults: count });\n            return jsonResult(result);\n          }\n\n          // ── Lists ───────────────────────────────────────────────────\n          case 'create_list': {\n            const name = readStringParam(p, 'list_name', { required: true })!;\n            const result = await x.createList({\n              name,\n              description: readStringParam(p, 'list_description'),\n              private: p.list_private as boolean | undefined,\n            });\n            return jsonResult({ status: 'created', list: result });\n          }\n\n          case 'delete_list': {\n            const listId = readStringParam(p, 'list_id', { required: true })!;\n            await x.deleteList(listId);\n            return jsonResult({ status: 'deleted', list_id: listId });\n          }\n\n          case 'get_list': {\n            const listId = readStringParam(p, 'list_id', { required: true })!;\n            const result = await x.getList(listId);\n            return jsonResult(result);\n          }\n\n          case 'get_user_lists': {\n            const username = readStringParam(p, 'username', { required: true })!;\n            const result = await x.getUserLists(username, { maxResults: count });\n            return jsonResult(result);\n          }\n\n          case 'add_list_member': {\n            const listId = readStringParam(p, 'list_id', { required: true })!;\n            const username = readStringParam(p, 'username', { required: true })!;\n            await x.addListMember(listId, username);\n            return jsonResult({ status: 'added', list_id: listId, username });\n          }\n\n          case 'remove_list_member': {\n            const listId = readStringParam(p, 'list_id', { required: true })!;\n            const username = readStringParam(p, 'username', { required: true })!;\n            await x.removeListMember(listId, username);\n            return jsonResult({ status: 'removed', list_id: listId, username });\n          }\n\n          case 'list_members': {\n            const listId = readStringParam(p, 'list_id', { required: true })!;\n            const result = await x.getListMembers(listId, { maxResults: count });\n            return jsonResult(result);\n          }\n\n          case 'list_tweets': {\n            const listId = readStringParam(p, 'list_id', { required: true })!;\n            const result = await x.getListTweets(listId, { maxResults: count });\n            return jsonResult(result);\n          }\n\n          // ── Streaming ───────────────────────────────────────────────\n          case 'stream_start': {\n            const duration = Math.min(readNumberParam(p, 'stream_duration') ?? 30, 300);\n            await x.stopStream(); // Stop any existing stream\n            const result = await x.streamFiltered({\n              durationMs: duration * 1000,\n              maxTweets: 50,\n            });\n            return jsonResult({ status: 'stream_complete', tweets: result });\n          }\n\n          case 'stream_stop': {\n            await x.stopStream();\n            return jsonResult({ status: 'stream_stopped' });\n          }\n\n          case 'stream_rules_set': {\n            const rulesStr = readStringParam(p, 'stream_rules', { required: true })!;\n            const rules = JSON.parse(rulesStr);\n            const result = await x.setStreamRules(rules);\n            return jsonResult({ status: 'rules_set', result });\n          }\n\n          case 'stream_rules_get': {\n            const result = await x.getStreamRules();\n            return jsonResult(result);\n          }\n\n          // ── Orchestration ───────────────────────────────────────────\n          case 'action_chain': {\n            const stepsStr = readStringParam(p, 'chain_steps', { required: true })!;\n            const steps = JSON.parse(stepsStr);\n            if (!Array.isArray(steps) || steps.length === 0) {\n              return errorResult('chain_steps must be a non-empty JSON array of action objects');\n            }\n\n            const results: any[] = [];\n            let prevMetadata: any = {};\n\n            for (let i = 0; i < steps.length; i++) {\n              const step = steps[i] as Record<string, unknown>;\n\n              // Substitute PREV_TWEET_ID placeholder\n              for (const [key, val] of Object.entries(step)) {\n                if (typeof val === 'string' && val.includes('PREV_TWEET_ID')) {\n                  step[key] = val.replace(\n                    'PREV_TWEET_ID',\n                    prevMetadata.tweet_id || prevMetadata.first_tweet_id || '',\n                  );\n                }\n              }\n\n              // Recursive call: extract action and pass full step as args\n              const stepAction = step.action as string;\n              if (!stepAction) {\n                results.push({ step: i, error: 'Missing action in chain step' });\n                break;\n              }\n\n              // Re-invoke this tool's execute with the step params\n              const stepResult = await createClawnXTool().execute(_toolCallId, step) as any;\n              const parsed = JSON.parse(stepResult.content[0]!.text);\n\n              if (stepResult.isError) {\n                results.push({ step: i, action: stepAction, error: parsed });\n                break;\n              }\n\n              results.push({ step: i, action: stepAction, result: parsed });\n              prevMetadata = parsed;\n            }\n\n            return jsonResult({ status: 'chain_complete', steps: results });\n          }\n\n          default:\n            return errorResult(`Unknown clawnx action: ${action}`);\n        }\n      } catch (err) {\n        return errorResult(`ClawnX error: ${err instanceof Error ? err.message : String(err)}`);\n      }\n    },\n  };\n}\n"],"mappings":"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"}