peak6-x-publishing-plugin 0.2.2 → 0.2.3
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/dist/manifest.js +1 -1
- package/dist/manifest.js.map +1 -1
- package/dist/worker.js +95 -86
- package/dist/worker.js.map +3 -3
- package/package.json +1 -1
package/dist/manifest.js
CHANGED
package/dist/manifest.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/constants.ts", "../src/manifest.ts"],
|
|
4
|
-
"sourcesContent": ["export const PLUGIN_ID = \"peak6-labs.x-publishing\";\nexport const PLUGIN_VERSION = \"0.2.2\";\n\nexport const TOOL_NAMES = {\n draftPost: \"draft-post\",\n updateDraft: \"update-draft\",\n publishPost: \"publish-post\",\n replyToTweet: \"reply-to-tweet\",\n quoteTweet: \"quote-tweet\",\n repost: \"repost\",\n schedulePost: \"schedule-post\",\n publishThread: \"publish-thread\",\n draftThread: \"draft-thread\",\n getDrafts: \"get-drafts\",\n getSchedule: \"get-schedule\",\n getPostMetrics: \"get-post-metrics\",\n getAccountStatus: \"get-account-status\",\n setupOauth: \"setup-oauth\",\n} as const;\n\nexport const JOB_KEYS = {\n tokenRefresh: \"token-refresh\",\n publishScheduled: \"publish-scheduled\",\n metricsCapture: \"metrics-capture\",\n staleDraftCleanup: \"stale-draft-cleanup\",\n} as const;\n\nexport const ENTITY_TYPES = {\n draft: \"draft\",\n publishedPost: \"published-post\",\n} as const;\n\nexport const EVENT_NAMES = {\n postPublished: \"post.published\",\n draftCreated: \"draft.created\",\n approvalRequired: \"approval.required\",\n postEngagementMilestone: \"post.engagement-milestone\",\n threadPublished: \"thread.published\",\n} as const;\n\nexport const STATE_KEYS = {\n oauthTokens: \"oauth_tokens\",\n rateLimits: \"rate_limits\",\n} as const;\n\nexport const SLOT_IDS = {\n dashboardWidget: \"x-publishing-dashboard\",\n settingsPage: \"x-publishing-settings\",\n contentPage: \"x-publishing-content\",\n} as const;\n\nexport const EXPORT_NAMES = {\n dashboardWidget: \"DashboardWidget\",\n settingsPage: \"SettingsPage\",\n contentPage: \"ContentPage\",\n} as const;\n\nexport type ApprovalMode = \"required\" | \"optional\" | \"none\";\n\nexport const DEFAULT_APPROVAL_MODES = {\n posts: \"none\" as ApprovalMode,\n replies: \"none\" as ApprovalMode,\n quotes: \"none\" as ApprovalMode,\n reposts: \"none\" as ApprovalMode,\n scheduled: \"required\" as ApprovalMode,\n};\n\nexport const DEFAULT_CONFIG = {\n company_id: \"\",\n oauth_client_id_ref: \"X_OAUTH_CLIENT_ID\",\n oauth_client_secret_ref: \"X_OAUTH_CLIENT_SECRET\",\n default_account: \"\",\n accounts: {} as Record<string, { x_handle: string; x_user_id: string; role: \"hub\" | \"spoke\"; approval_modes: typeof DEFAULT_APPROVAL_MODES }>,\n daily_post_limit: 25,\n engagement_milestones: [50, 100, 500, 1000],\n metrics_capture_lookback_days: 7,\n alert_agents: [] as Array<{ agentId: string; memoryFile: string | null }>,\n} as const;\n\n/** Build per-account state key */\nexport function accountStateKey(base: string, handle: string): string {\n return `${base}:${handle}`;\n}\n", "import type { PaperclipPluginManifestV1 } from \"@paperclipai/plugin-sdk\";\nimport {\n DEFAULT_CONFIG,\n EXPORT_NAMES,\n JOB_KEYS,\n PLUGIN_ID,\n PLUGIN_VERSION,\n SLOT_IDS,\n TOOL_NAMES,\n} from \"./constants.js\";\n\nconst manifest: PaperclipPluginManifestV1 = {\n id: PLUGIN_ID,\n apiVersion: 1,\n version: PLUGIN_VERSION,\n displayName: \"X Publishing\",\n description:\n \"X/Twitter publishing plugin \u2014 drafts, approvals, scheduling, threads, metrics capture, and cross-plugin event flow.\",\n author: \"peak6-labs\",\n categories: [\"connector\", \"automation\"],\n capabilities: [\n \"http.outbound\",\n \"secrets.read-ref\",\n \"jobs.schedule\",\n \"agent.tools.register\",\n \"plugin.state.read\",\n \"plugin.state.write\",\n \"events.subscribe\",\n \"events.emit\",\n \"issues.read\",\n \"issues.create\",\n \"issues.update\",\n \"activity.log.write\",\n \"metrics.write\",\n \"instance.settings.register\",\n \"ui.dashboardWidget.register\",\n \"ui.page.register\",\n ],\n entrypoints: {\n worker: \"./dist/worker.js\",\n ui: \"./dist/ui\",\n },\n instanceConfigSchema: {\n type: \"object\",\n properties: {\n company_id: {\n type: \"string\",\n title: \"Company ID\",\n description: \"UUID of the company this plugin serves\",\n default: DEFAULT_CONFIG.company_id,\n },\n oauth_client_id_ref: {\n type: \"string\",\n title: \"OAuth Client ID Secret Reference\",\n description: \"Shared across all accounts (one X Developer App)\",\n default: DEFAULT_CONFIG.oauth_client_id_ref,\n },\n oauth_client_secret_ref: {\n type: \"string\",\n title: \"OAuth Client Secret Reference\",\n default: DEFAULT_CONFIG.oauth_client_secret_ref,\n },\n default_account: {\n type: \"string\",\n title: \"Default Account\",\n description: \"Handle of the default account (used when tools omit account param)\",\n },\n accounts: {\n type: \"object\",\n title: \"Accounts\",\n description: \"Map of X accounts keyed by handle (without @)\",\n additionalProperties: {\n type: \"object\",\n properties: {\n x_handle: { type: \"string\", description: \"X handle (without @)\" },\n x_user_id: { type: \"string\", description: \"Numeric X user ID\" },\n role: { type: \"string\", enum: [\"hub\", \"spoke\"], default: \"spoke\" },\n approval_modes: {\n type: \"object\",\n properties: {\n posts: { type: \"string\", enum: [\"required\", \"optional\", \"none\"], default: \"none\" },\n replies: { type: \"string\", enum: [\"required\", \"optional\", \"none\"], default: \"none\" },\n quotes: { type: \"string\", enum: [\"required\", \"optional\", \"none\"], default: \"none\" },\n reposts: { type: \"string\", enum: [\"required\", \"optional\", \"none\"], default: \"none\" },\n scheduled: { type: \"string\", enum: [\"required\", \"optional\", \"none\"], default: \"required\" },\n },\n },\n },\n required: [\"x_handle\", \"x_user_id\"],\n },\n },\n daily_post_limit: {\n type: \"number\",\n title: \"Daily Post Limit\",\n description: \"Maximum posts per day per account (safety guardrail)\",\n default: DEFAULT_CONFIG.daily_post_limit,\n },\n engagement_milestones: {\n type: \"array\",\n title: \"Engagement Milestones\",\n description: \"Total engagement thresholds that trigger milestone events\",\n items: { type: \"number\" },\n default: DEFAULT_CONFIG.engagement_milestones,\n },\n metrics_capture_lookback_days: {\n type: \"number\",\n title: \"Metrics Capture Lookback (days)\",\n default: DEFAULT_CONFIG.metrics_capture_lookback_days,\n },\n alert_agents: {\n type: \"array\",\n title: \"Alert Agents\",\n description: \"Agents to notify on failures or milestones\",\n items: {\n type: \"object\",\n properties: {\n agentId: { type: \"string\", description: \"Paperclip agent UUID\" },\n memoryFile: { type: [\"string\", \"null\"], description: \"Path to user memory file\" },\n },\n required: [\"agentId\"],\n },\n default: DEFAULT_CONFIG.alert_agents,\n },\n },\n },\n jobs: [\n {\n jobKey: JOB_KEYS.tokenRefresh,\n displayName: \"Token Refresh\",\n description: \"Refresh OAuth2 access token before expiry. Alerts on failure.\",\n schedule: \"0 */2 * * *\", // every 2 hours\n },\n {\n jobKey: JOB_KEYS.publishScheduled,\n displayName: \"Publish Scheduled\",\n description: \"Publish approved drafts whose schedule_at has passed.\",\n schedule: \"*/15 * * * *\", // every 15 min\n },\n {\n jobKey: JOB_KEYS.metricsCapture,\n displayName: \"Metrics Capture\",\n description: \"Snapshot engagement metrics on recent published posts.\",\n schedule: \"0 */6 * * *\", // every 6 hours\n },\n {\n jobKey: JOB_KEYS.staleDraftCleanup,\n displayName: \"Stale Draft Cleanup\",\n description: \"Mark drafts older than 48h in draft/in_review status as stale.\",\n schedule: \"0 2 * * *\", // daily at 2 AM\n },\n ],\n tools: [\n {\n name: TOOL_NAMES.setupOauth,\n displayName: \"Setup OAuth\",\n description: \"Seed initial OAuth tokens from a manual PKCE flow. Call once per account during setup.\",\n parametersSchema: {\n type: \"object\",\n properties: {\n account: { type: \"string\", description: \"X handle to store tokens for (must exist in accounts config)\" },\n access_token: { type: \"string\", description: \"OAuth2 access token\" },\n refresh_token: { type: \"string\", description: \"OAuth2 refresh token\" },\n expires_in: { type: \"number\", description: \"Token TTL in seconds (default 7200)\" },\n },\n required: [\"account\", \"access_token\", \"refresh_token\"],\n },\n },\n {\n name: TOOL_NAMES.draftPost,\n displayName: \"Draft Post\",\n description: \"Create a draft post for review or later publishing.\",\n parametersSchema: {\n type: \"object\",\n properties: {\n text: { type: \"string\", description: \"Tweet text (max 280 chars)\" },\n format: { type: \"string\", enum: [\"single\", \"reply\", \"quote\"], description: \"Post format\" },\n reply_to_tweet_id: { type: \"string\", description: \"Tweet ID to reply to (for reply format)\" },\n quote_tweet_id: { type: \"string\", description: \"Tweet ID to quote (for quote format)\" },\n schedule_at: { type: \"string\", description: \"ISO datetime to schedule publication\" },\n metadata: {\n type: \"object\",\n description: \"Content metadata for feedback loop\",\n properties: {\n voice: { type: \"string\" },\n content_bucket: { type: \"string\" },\n topic: { type: \"string\" },\n source_tweet_id: { type: \"string\" },\n source_issue_id: { type: \"string\" },\n },\n },\n },\n required: [\"text\"],\n },\n },\n {\n name: TOOL_NAMES.draftThread,\n displayName: \"Draft Thread\",\n description: \"Create a draft thread (multiple tweets posted as a reply chain).\",\n parametersSchema: {\n type: \"object\",\n properties: {\n thread_tweets: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Array of tweet texts (each max 280 chars)\",\n },\n schedule_at: { type: \"string\", description: \"ISO datetime to schedule publication\" },\n metadata: {\n type: \"object\",\n properties: {\n voice: { type: \"string\" },\n content_bucket: { type: \"string\" },\n topic: { type: \"string\" },\n source_tweet_id: { type: \"string\" },\n source_issue_id: { type: \"string\" },\n },\n },\n },\n required: [\"thread_tweets\"],\n },\n },\n {\n name: TOOL_NAMES.updateDraft,\n displayName: \"Update Draft\",\n description: \"Update an existing draft's text, metadata, or schedule.\",\n parametersSchema: {\n type: \"object\",\n properties: {\n draft_id: { type: \"string\", description: \"Draft entity ID\" },\n text: { type: \"string\", description: \"Updated tweet text\" },\n thread_tweets: { type: \"array\", items: { type: \"string\" } },\n schedule_at: { type: \"string\" },\n metadata: {\n type: \"object\",\n properties: {\n voice: { type: \"string\" },\n content_bucket: { type: \"string\" },\n topic: { type: \"string\" },\n source_tweet_id: { type: \"string\" },\n source_issue_id: { type: \"string\" },\n },\n },\n },\n required: [\"draft_id\"],\n },\n },\n {\n name: TOOL_NAMES.publishPost,\n displayName: \"Publish Post\",\n description: \"Publish a tweet to X. Accepts inline text or a draft_id.\",\n parametersSchema: {\n type: \"object\",\n properties: {\n account: { type: \"string\", description: \"X handle to post as (defaults to default_account)\" },\n text: { type: \"string\", description: \"Tweet text (if publishing inline)\" },\n draft_id: { type: \"string\", description: \"Draft entity ID (if publishing from draft)\" },\n metadata: {\n type: \"object\",\n properties: {\n voice: { type: \"string\" },\n content_bucket: { type: \"string\" },\n topic: { type: \"string\" },\n source_tweet_id: { type: \"string\" },\n },\n },\n },\n },\n },\n {\n name: TOOL_NAMES.replyToTweet,\n displayName: \"Reply to Tweet\",\n description: \"Post a reply to an existing tweet on X.\",\n parametersSchema: {\n type: \"object\",\n properties: {\n account: { type: \"string\", description: \"X handle to post as (defaults to default_account)\" },\n tweet_id: { type: \"string\", description: \"Tweet ID to reply to\" },\n text: { type: \"string\", description: \"Reply text (max 280 chars)\" },\n draft_id: { type: \"string\", description: \"Draft entity ID (if from draft)\" },\n metadata: {\n type: \"object\",\n properties: {\n voice: { type: \"string\" },\n content_bucket: { type: \"string\" },\n topic: { type: \"string\" },\n source_tweet_id: { type: \"string\" },\n },\n },\n },\n required: [\"tweet_id\", \"text\"],\n },\n },\n {\n name: TOOL_NAMES.quoteTweet,\n displayName: \"Quote Tweet\",\n description: \"Post a quote tweet on X.\",\n parametersSchema: {\n type: \"object\",\n properties: {\n account: { type: \"string\", description: \"X handle to post as (defaults to default_account)\" },\n tweet_id: { type: \"string\", description: \"Tweet ID to quote\" },\n text: { type: \"string\", description: \"Quote text (max 280 chars)\" },\n draft_id: { type: \"string\", description: \"Draft entity ID (if from draft)\" },\n metadata: {\n type: \"object\",\n properties: {\n voice: { type: \"string\" },\n content_bucket: { type: \"string\" },\n topic: { type: \"string\" },\n source_tweet_id: { type: \"string\" },\n },\n },\n },\n required: [\"tweet_id\", \"text\"],\n },\n },\n {\n name: TOOL_NAMES.repost,\n displayName: \"Repost\",\n description: \"Repost (retweet) an existing tweet on X.\",\n parametersSchema: {\n type: \"object\",\n properties: {\n account: { type: \"string\", description: \"X handle to post as (defaults to default_account)\" },\n tweet_id: { type: \"string\", description: \"Tweet ID to repost\" },\n draft_id: { type: \"string\", description: \"Draft entity ID (if from draft)\" },\n },\n required: [\"tweet_id\"],\n },\n },\n {\n name: TOOL_NAMES.schedulePost,\n displayName: \"Schedule Post\",\n description: \"Create or update a draft with a scheduled publication time.\",\n parametersSchema: {\n type: \"object\",\n properties: {\n draft_id: { type: \"string\", description: \"Existing draft ID to schedule\" },\n text: { type: \"string\", description: \"Tweet text (creates new draft if no draft_id)\" },\n schedule_at: { type: \"string\", description: \"ISO datetime for publication\" },\n metadata: {\n type: \"object\",\n properties: {\n voice: { type: \"string\" },\n content_bucket: { type: \"string\" },\n topic: { type: \"string\" },\n source_tweet_id: { type: \"string\" },\n },\n },\n },\n required: [\"schedule_at\"],\n },\n },\n {\n name: TOOL_NAMES.publishThread,\n displayName: \"Publish Thread\",\n description: \"Publish a multi-tweet thread to X with reply chaining. Retries on failure; leaves partial thread + alert on persistent failure.\",\n parametersSchema: {\n type: \"object\",\n properties: {\n account: { type: \"string\", description: \"X handle to post as (defaults to default_account)\" },\n thread_tweets: { type: \"array\", items: { type: \"string\" }, description: \"Array of tweet texts\" },\n draft_id: { type: \"string\", description: \"Draft entity ID (if from draft)\" },\n metadata: {\n type: \"object\",\n properties: {\n voice: { type: \"string\" },\n content_bucket: { type: \"string\" },\n topic: { type: \"string\" },\n source_tweet_id: { type: \"string\" },\n },\n },\n },\n },\n },\n {\n name: TOOL_NAMES.getDrafts,\n displayName: \"Get Drafts\",\n description: \"Query draft entities, optionally filtered by status.\",\n parametersSchema: {\n type: \"object\",\n properties: {\n status: { type: \"string\", enum: [\"draft\", \"in_review\", \"approved\", \"rejected\", \"stale\"], description: \"Filter by draft status\" },\n limit: { type: \"number\", description: \"Max results (default 20)\" },\n },\n },\n },\n {\n name: TOOL_NAMES.getSchedule,\n displayName: \"Get Schedule\",\n description: \"Get upcoming scheduled posts (drafts with schedule_at set).\",\n parametersSchema: {\n type: \"object\",\n properties: {\n limit: { type: \"number\", description: \"Max results (default 20)\" },\n },\n },\n },\n {\n name: TOOL_NAMES.getPostMetrics,\n displayName: \"Get Post Metrics\",\n description: \"Get engagement metrics for a published post.\",\n parametersSchema: {\n type: \"object\",\n properties: {\n tweet_id: { type: \"string\", description: \"Tweet ID to get metrics for\" },\n },\n required: [\"tweet_id\"],\n },\n },\n {\n name: TOOL_NAMES.getAccountStatus,\n displayName: \"Get Account Status\",\n description: \"Get account health: rate limits, daily post count, token validity. Returns all accounts if no account specified.\",\n parametersSchema: {\n type: \"object\",\n properties: {\n account: { type: \"string\", description: \"X handle (omit for all accounts)\" },\n },\n },\n },\n ],\n ui: {\n slots: [\n {\n type: \"dashboardWidget\",\n id: SLOT_IDS.dashboardWidget,\n displayName: \"X Publishing\",\n exportName: EXPORT_NAMES.dashboardWidget,\n },\n {\n type: \"settingsPage\",\n id: SLOT_IDS.settingsPage,\n displayName: \"X Publishing Settings\",\n exportName: EXPORT_NAMES.settingsPage,\n },\n {\n type: \"page\",\n id: SLOT_IDS.contentPage,\n displayName: \"Content Queue\",\n exportName: EXPORT_NAMES.contentPage,\n routePath: \"x-publishing\",\n },\n ],\n },\n};\n\nexport default manifest;\n"],
|
|
4
|
+
"sourcesContent": ["export const PLUGIN_ID = \"peak6-labs.x-publishing\";\nexport const PLUGIN_VERSION = \"0.2.3\";\n\nexport const TOOL_NAMES = {\n draftPost: \"draft-post\",\n updateDraft: \"update-draft\",\n publishPost: \"publish-post\",\n replyToTweet: \"reply-to-tweet\",\n quoteTweet: \"quote-tweet\",\n repost: \"repost\",\n schedulePost: \"schedule-post\",\n publishThread: \"publish-thread\",\n draftThread: \"draft-thread\",\n getDrafts: \"get-drafts\",\n getSchedule: \"get-schedule\",\n getPostMetrics: \"get-post-metrics\",\n getAccountStatus: \"get-account-status\",\n setupOauth: \"setup-oauth\",\n} as const;\n\nexport const JOB_KEYS = {\n tokenRefresh: \"token-refresh\",\n publishScheduled: \"publish-scheduled\",\n metricsCapture: \"metrics-capture\",\n staleDraftCleanup: \"stale-draft-cleanup\",\n} as const;\n\nexport const ENTITY_TYPES = {\n draft: \"draft\",\n publishedPost: \"published-post\",\n} as const;\n\nexport const EVENT_NAMES = {\n postPublished: \"post.published\",\n draftCreated: \"draft.created\",\n approvalRequired: \"approval.required\",\n postEngagementMilestone: \"post.engagement-milestone\",\n threadPublished: \"thread.published\",\n} as const;\n\nexport const STATE_KEYS = {\n oauthTokens: \"oauth_tokens\",\n rateLimits: \"rate_limits\",\n} as const;\n\nexport const SLOT_IDS = {\n dashboardWidget: \"x-publishing-dashboard\",\n settingsPage: \"x-publishing-settings\",\n contentPage: \"x-publishing-content\",\n} as const;\n\nexport const EXPORT_NAMES = {\n dashboardWidget: \"DashboardWidget\",\n settingsPage: \"SettingsPage\",\n contentPage: \"ContentPage\",\n} as const;\n\nexport type ApprovalMode = \"required\" | \"optional\" | \"none\";\n\nexport const DEFAULT_APPROVAL_MODES = {\n posts: \"none\" as ApprovalMode,\n replies: \"none\" as ApprovalMode,\n quotes: \"none\" as ApprovalMode,\n reposts: \"none\" as ApprovalMode,\n scheduled: \"required\" as ApprovalMode,\n};\n\nexport const DEFAULT_CONFIG = {\n company_id: \"\",\n oauth_client_id_ref: \"X_OAUTH_CLIENT_ID\",\n oauth_client_secret_ref: \"X_OAUTH_CLIENT_SECRET\",\n default_account: \"\",\n accounts: {} as Record<string, { x_handle: string; x_user_id: string; role: \"hub\" | \"spoke\"; approval_modes: typeof DEFAULT_APPROVAL_MODES }>,\n daily_post_limit: 25,\n engagement_milestones: [50, 100, 500, 1000],\n metrics_capture_lookback_days: 7,\n alert_agents: [] as Array<{ agentId: string; memoryFile: string | null }>,\n} as const;\n\n/** Build per-account state key */\nexport function accountStateKey(base: string, handle: string): string {\n return `${base}:${handle}`;\n}\n", "import type { PaperclipPluginManifestV1 } from \"@paperclipai/plugin-sdk\";\nimport {\n DEFAULT_CONFIG,\n EXPORT_NAMES,\n JOB_KEYS,\n PLUGIN_ID,\n PLUGIN_VERSION,\n SLOT_IDS,\n TOOL_NAMES,\n} from \"./constants.js\";\n\nconst manifest: PaperclipPluginManifestV1 = {\n id: PLUGIN_ID,\n apiVersion: 1,\n version: PLUGIN_VERSION,\n displayName: \"X Publishing\",\n description:\n \"X/Twitter publishing plugin \u2014 drafts, approvals, scheduling, threads, metrics capture, and cross-plugin event flow.\",\n author: \"peak6-labs\",\n categories: [\"connector\", \"automation\"],\n capabilities: [\n \"http.outbound\",\n \"secrets.read-ref\",\n \"jobs.schedule\",\n \"agent.tools.register\",\n \"plugin.state.read\",\n \"plugin.state.write\",\n \"events.subscribe\",\n \"events.emit\",\n \"issues.read\",\n \"issues.create\",\n \"issues.update\",\n \"activity.log.write\",\n \"metrics.write\",\n \"instance.settings.register\",\n \"ui.dashboardWidget.register\",\n \"ui.page.register\",\n ],\n entrypoints: {\n worker: \"./dist/worker.js\",\n ui: \"./dist/ui\",\n },\n instanceConfigSchema: {\n type: \"object\",\n properties: {\n company_id: {\n type: \"string\",\n title: \"Company ID\",\n description: \"UUID of the company this plugin serves\",\n default: DEFAULT_CONFIG.company_id,\n },\n oauth_client_id_ref: {\n type: \"string\",\n title: \"OAuth Client ID Secret Reference\",\n description: \"Shared across all accounts (one X Developer App)\",\n default: DEFAULT_CONFIG.oauth_client_id_ref,\n },\n oauth_client_secret_ref: {\n type: \"string\",\n title: \"OAuth Client Secret Reference\",\n default: DEFAULT_CONFIG.oauth_client_secret_ref,\n },\n default_account: {\n type: \"string\",\n title: \"Default Account\",\n description: \"Handle of the default account (used when tools omit account param)\",\n },\n accounts: {\n type: \"object\",\n title: \"Accounts\",\n description: \"Map of X accounts keyed by handle (without @)\",\n additionalProperties: {\n type: \"object\",\n properties: {\n x_handle: { type: \"string\", description: \"X handle (without @)\" },\n x_user_id: { type: \"string\", description: \"Numeric X user ID\" },\n role: { type: \"string\", enum: [\"hub\", \"spoke\"], default: \"spoke\" },\n approval_modes: {\n type: \"object\",\n properties: {\n posts: { type: \"string\", enum: [\"required\", \"optional\", \"none\"], default: \"none\" },\n replies: { type: \"string\", enum: [\"required\", \"optional\", \"none\"], default: \"none\" },\n quotes: { type: \"string\", enum: [\"required\", \"optional\", \"none\"], default: \"none\" },\n reposts: { type: \"string\", enum: [\"required\", \"optional\", \"none\"], default: \"none\" },\n scheduled: { type: \"string\", enum: [\"required\", \"optional\", \"none\"], default: \"required\" },\n },\n },\n },\n required: [\"x_handle\", \"x_user_id\"],\n },\n },\n daily_post_limit: {\n type: \"number\",\n title: \"Daily Post Limit\",\n description: \"Maximum posts per day per account (safety guardrail)\",\n default: DEFAULT_CONFIG.daily_post_limit,\n },\n engagement_milestones: {\n type: \"array\",\n title: \"Engagement Milestones\",\n description: \"Total engagement thresholds that trigger milestone events\",\n items: { type: \"number\" },\n default: DEFAULT_CONFIG.engagement_milestones,\n },\n metrics_capture_lookback_days: {\n type: \"number\",\n title: \"Metrics Capture Lookback (days)\",\n default: DEFAULT_CONFIG.metrics_capture_lookback_days,\n },\n alert_agents: {\n type: \"array\",\n title: \"Alert Agents\",\n description: \"Agents to notify on failures or milestones\",\n items: {\n type: \"object\",\n properties: {\n agentId: { type: \"string\", description: \"Paperclip agent UUID\" },\n memoryFile: { type: [\"string\", \"null\"], description: \"Path to user memory file\" },\n },\n required: [\"agentId\"],\n },\n default: DEFAULT_CONFIG.alert_agents,\n },\n },\n },\n jobs: [\n {\n jobKey: JOB_KEYS.tokenRefresh,\n displayName: \"Token Refresh\",\n description: \"Refresh OAuth2 access token before expiry. Alerts on failure.\",\n schedule: \"0 */2 * * *\", // every 2 hours\n },\n {\n jobKey: JOB_KEYS.publishScheduled,\n displayName: \"Publish Scheduled\",\n description: \"Publish approved drafts whose schedule_at has passed.\",\n schedule: \"*/15 * * * *\", // every 15 min\n },\n {\n jobKey: JOB_KEYS.metricsCapture,\n displayName: \"Metrics Capture\",\n description: \"Snapshot engagement metrics on recent published posts.\",\n schedule: \"0 */6 * * *\", // every 6 hours\n },\n {\n jobKey: JOB_KEYS.staleDraftCleanup,\n displayName: \"Stale Draft Cleanup\",\n description: \"Mark drafts older than 48h in draft/in_review status as stale.\",\n schedule: \"0 2 * * *\", // daily at 2 AM\n },\n ],\n tools: [\n {\n name: TOOL_NAMES.setupOauth,\n displayName: \"Setup OAuth\",\n description: \"Seed initial OAuth tokens from a manual PKCE flow. Call once per account during setup.\",\n parametersSchema: {\n type: \"object\",\n properties: {\n account: { type: \"string\", description: \"X handle to store tokens for (must exist in accounts config)\" },\n access_token: { type: \"string\", description: \"OAuth2 access token\" },\n refresh_token: { type: \"string\", description: \"OAuth2 refresh token\" },\n expires_in: { type: \"number\", description: \"Token TTL in seconds (default 7200)\" },\n },\n required: [\"account\", \"access_token\", \"refresh_token\"],\n },\n },\n {\n name: TOOL_NAMES.draftPost,\n displayName: \"Draft Post\",\n description: \"Create a draft post for review or later publishing.\",\n parametersSchema: {\n type: \"object\",\n properties: {\n text: { type: \"string\", description: \"Tweet text (max 280 chars)\" },\n format: { type: \"string\", enum: [\"single\", \"reply\", \"quote\"], description: \"Post format\" },\n reply_to_tweet_id: { type: \"string\", description: \"Tweet ID to reply to (for reply format)\" },\n quote_tweet_id: { type: \"string\", description: \"Tweet ID to quote (for quote format)\" },\n schedule_at: { type: \"string\", description: \"ISO datetime to schedule publication\" },\n metadata: {\n type: \"object\",\n description: \"Content metadata for feedback loop\",\n properties: {\n voice: { type: \"string\" },\n content_bucket: { type: \"string\" },\n topic: { type: \"string\" },\n source_tweet_id: { type: \"string\" },\n source_issue_id: { type: \"string\" },\n },\n },\n },\n required: [\"text\"],\n },\n },\n {\n name: TOOL_NAMES.draftThread,\n displayName: \"Draft Thread\",\n description: \"Create a draft thread (multiple tweets posted as a reply chain).\",\n parametersSchema: {\n type: \"object\",\n properties: {\n thread_tweets: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Array of tweet texts (each max 280 chars)\",\n },\n schedule_at: { type: \"string\", description: \"ISO datetime to schedule publication\" },\n metadata: {\n type: \"object\",\n properties: {\n voice: { type: \"string\" },\n content_bucket: { type: \"string\" },\n topic: { type: \"string\" },\n source_tweet_id: { type: \"string\" },\n source_issue_id: { type: \"string\" },\n },\n },\n },\n required: [\"thread_tweets\"],\n },\n },\n {\n name: TOOL_NAMES.updateDraft,\n displayName: \"Update Draft\",\n description: \"Update an existing draft's text, metadata, or schedule.\",\n parametersSchema: {\n type: \"object\",\n properties: {\n draft_id: { type: \"string\", description: \"Draft entity ID\" },\n text: { type: \"string\", description: \"Updated tweet text\" },\n thread_tweets: { type: \"array\", items: { type: \"string\" } },\n schedule_at: { type: \"string\" },\n metadata: {\n type: \"object\",\n properties: {\n voice: { type: \"string\" },\n content_bucket: { type: \"string\" },\n topic: { type: \"string\" },\n source_tweet_id: { type: \"string\" },\n source_issue_id: { type: \"string\" },\n },\n },\n },\n required: [\"draft_id\"],\n },\n },\n {\n name: TOOL_NAMES.publishPost,\n displayName: \"Publish Post\",\n description: \"Publish a tweet to X. Accepts inline text or a draft_id.\",\n parametersSchema: {\n type: \"object\",\n properties: {\n account: { type: \"string\", description: \"X handle to post as (defaults to default_account)\" },\n text: { type: \"string\", description: \"Tweet text (if publishing inline)\" },\n draft_id: { type: \"string\", description: \"Draft entity ID (if publishing from draft)\" },\n metadata: {\n type: \"object\",\n properties: {\n voice: { type: \"string\" },\n content_bucket: { type: \"string\" },\n topic: { type: \"string\" },\n source_tweet_id: { type: \"string\" },\n },\n },\n },\n },\n },\n {\n name: TOOL_NAMES.replyToTweet,\n displayName: \"Reply to Tweet\",\n description: \"Post a reply to an existing tweet on X.\",\n parametersSchema: {\n type: \"object\",\n properties: {\n account: { type: \"string\", description: \"X handle to post as (defaults to default_account)\" },\n tweet_id: { type: \"string\", description: \"Tweet ID to reply to\" },\n text: { type: \"string\", description: \"Reply text (max 280 chars)\" },\n draft_id: { type: \"string\", description: \"Draft entity ID (if from draft)\" },\n metadata: {\n type: \"object\",\n properties: {\n voice: { type: \"string\" },\n content_bucket: { type: \"string\" },\n topic: { type: \"string\" },\n source_tweet_id: { type: \"string\" },\n },\n },\n },\n required: [\"tweet_id\", \"text\"],\n },\n },\n {\n name: TOOL_NAMES.quoteTweet,\n displayName: \"Quote Tweet\",\n description: \"Post a quote tweet on X.\",\n parametersSchema: {\n type: \"object\",\n properties: {\n account: { type: \"string\", description: \"X handle to post as (defaults to default_account)\" },\n tweet_id: { type: \"string\", description: \"Tweet ID to quote\" },\n text: { type: \"string\", description: \"Quote text (max 280 chars)\" },\n draft_id: { type: \"string\", description: \"Draft entity ID (if from draft)\" },\n metadata: {\n type: \"object\",\n properties: {\n voice: { type: \"string\" },\n content_bucket: { type: \"string\" },\n topic: { type: \"string\" },\n source_tweet_id: { type: \"string\" },\n },\n },\n },\n required: [\"tweet_id\", \"text\"],\n },\n },\n {\n name: TOOL_NAMES.repost,\n displayName: \"Repost\",\n description: \"Repost (retweet) an existing tweet on X.\",\n parametersSchema: {\n type: \"object\",\n properties: {\n account: { type: \"string\", description: \"X handle to post as (defaults to default_account)\" },\n tweet_id: { type: \"string\", description: \"Tweet ID to repost\" },\n draft_id: { type: \"string\", description: \"Draft entity ID (if from draft)\" },\n },\n required: [\"tweet_id\"],\n },\n },\n {\n name: TOOL_NAMES.schedulePost,\n displayName: \"Schedule Post\",\n description: \"Create or update a draft with a scheduled publication time.\",\n parametersSchema: {\n type: \"object\",\n properties: {\n draft_id: { type: \"string\", description: \"Existing draft ID to schedule\" },\n text: { type: \"string\", description: \"Tweet text (creates new draft if no draft_id)\" },\n schedule_at: { type: \"string\", description: \"ISO datetime for publication\" },\n metadata: {\n type: \"object\",\n properties: {\n voice: { type: \"string\" },\n content_bucket: { type: \"string\" },\n topic: { type: \"string\" },\n source_tweet_id: { type: \"string\" },\n },\n },\n },\n required: [\"schedule_at\"],\n },\n },\n {\n name: TOOL_NAMES.publishThread,\n displayName: \"Publish Thread\",\n description: \"Publish a multi-tweet thread to X with reply chaining. Retries on failure; leaves partial thread + alert on persistent failure.\",\n parametersSchema: {\n type: \"object\",\n properties: {\n account: { type: \"string\", description: \"X handle to post as (defaults to default_account)\" },\n thread_tweets: { type: \"array\", items: { type: \"string\" }, description: \"Array of tweet texts\" },\n draft_id: { type: \"string\", description: \"Draft entity ID (if from draft)\" },\n metadata: {\n type: \"object\",\n properties: {\n voice: { type: \"string\" },\n content_bucket: { type: \"string\" },\n topic: { type: \"string\" },\n source_tweet_id: { type: \"string\" },\n },\n },\n },\n },\n },\n {\n name: TOOL_NAMES.getDrafts,\n displayName: \"Get Drafts\",\n description: \"Query draft entities, optionally filtered by status.\",\n parametersSchema: {\n type: \"object\",\n properties: {\n status: { type: \"string\", enum: [\"draft\", \"in_review\", \"approved\", \"rejected\", \"stale\"], description: \"Filter by draft status\" },\n limit: { type: \"number\", description: \"Max results (default 20)\" },\n },\n },\n },\n {\n name: TOOL_NAMES.getSchedule,\n displayName: \"Get Schedule\",\n description: \"Get upcoming scheduled posts (drafts with schedule_at set).\",\n parametersSchema: {\n type: \"object\",\n properties: {\n limit: { type: \"number\", description: \"Max results (default 20)\" },\n },\n },\n },\n {\n name: TOOL_NAMES.getPostMetrics,\n displayName: \"Get Post Metrics\",\n description: \"Get engagement metrics for a published post.\",\n parametersSchema: {\n type: \"object\",\n properties: {\n tweet_id: { type: \"string\", description: \"Tweet ID to get metrics for\" },\n },\n required: [\"tweet_id\"],\n },\n },\n {\n name: TOOL_NAMES.getAccountStatus,\n displayName: \"Get Account Status\",\n description: \"Get account health: rate limits, daily post count, token validity. Returns all accounts if no account specified.\",\n parametersSchema: {\n type: \"object\",\n properties: {\n account: { type: \"string\", description: \"X handle (omit for all accounts)\" },\n },\n },\n },\n ],\n ui: {\n slots: [\n {\n type: \"dashboardWidget\",\n id: SLOT_IDS.dashboardWidget,\n displayName: \"X Publishing\",\n exportName: EXPORT_NAMES.dashboardWidget,\n },\n {\n type: \"settingsPage\",\n id: SLOT_IDS.settingsPage,\n displayName: \"X Publishing Settings\",\n exportName: EXPORT_NAMES.settingsPage,\n },\n {\n type: \"page\",\n id: SLOT_IDS.contentPage,\n displayName: \"Content Queue\",\n exportName: EXPORT_NAMES.contentPage,\n routePath: \"x-publishing\",\n },\n ],\n },\n};\n\nexport default manifest;\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/worker.js
CHANGED
|
@@ -965,10 +965,10 @@ async function setTokens(ctx, handle, tokens) {
|
|
|
965
965
|
tokens
|
|
966
966
|
);
|
|
967
967
|
}
|
|
968
|
-
async function refreshTokens(ctx,
|
|
968
|
+
async function refreshTokens(ctx, config2, handle) {
|
|
969
969
|
const current = await getTokens(ctx, handle);
|
|
970
|
-
const clientId = await ctx.secrets.resolve(
|
|
971
|
-
const clientSecret = await ctx.secrets.resolve(
|
|
970
|
+
const clientId = await ctx.secrets.resolve(config2.oauth_client_id_ref);
|
|
971
|
+
const clientSecret = await ctx.secrets.resolve(config2.oauth_client_secret_ref);
|
|
972
972
|
const resp = await ctx.http.fetch("https://api.x.com/2/oauth2/token", {
|
|
973
973
|
method: "POST",
|
|
974
974
|
headers: {
|
|
@@ -993,10 +993,10 @@ async function refreshTokens(ctx, config, handle) {
|
|
|
993
993
|
await setTokens(ctx, handle, newTokens);
|
|
994
994
|
return newTokens;
|
|
995
995
|
}
|
|
996
|
-
async function getValidAccessToken(ctx,
|
|
996
|
+
async function getValidAccessToken(ctx, config2, handle) {
|
|
997
997
|
const tokens = await getTokens(ctx, handle);
|
|
998
998
|
if (tokens.expires_at - Date.now() < REFRESH_BUFFER_MS) {
|
|
999
|
-
const refreshed = await refreshTokens(ctx,
|
|
999
|
+
const refreshed = await refreshTokens(ctx, config2, handle);
|
|
1000
1000
|
return refreshed.access_token;
|
|
1001
1001
|
}
|
|
1002
1002
|
return tokens.access_token;
|
|
@@ -1132,7 +1132,7 @@ async function updateRateLimits(ctx, handle, endpoint, headers) {
|
|
|
1132
1132
|
}
|
|
1133
1133
|
|
|
1134
1134
|
// src/pipeline/approval-gate.ts
|
|
1135
|
-
async function checkApproval(ctx,
|
|
1135
|
+
async function checkApproval(ctx, config2, contentType, draftId, approvalModes) {
|
|
1136
1136
|
const modes = approvalModes || DEFAULT_APPROVAL_MODES;
|
|
1137
1137
|
const mode = modes[contentType];
|
|
1138
1138
|
if (mode === "none") {
|
|
@@ -1144,14 +1144,14 @@ async function checkApproval(ctx, config, contentType, draftId, approvalModes) {
|
|
|
1144
1144
|
}
|
|
1145
1145
|
if (!draftId) {
|
|
1146
1146
|
const issue = await ctx.issues.create({
|
|
1147
|
-
companyId:
|
|
1147
|
+
companyId: config2.company_id,
|
|
1148
1148
|
title: `Approval required for ${contentType}`,
|
|
1149
1149
|
description: `Content type "${contentType}" requires approval but no draft was provided for review.
|
|
1150
1150
|
|
|
1151
1151
|
Create a draft first, then have it approved before publishing.`
|
|
1152
1152
|
});
|
|
1153
|
-
await ctx.issues.update(issue.id, { status: "todo" },
|
|
1154
|
-
await ctx.events.emit(EVENT_NAMES.approvalRequired,
|
|
1153
|
+
await ctx.issues.update(issue.id, { status: "todo" }, config2.company_id);
|
|
1154
|
+
await ctx.events.emit(EVENT_NAMES.approvalRequired, config2.company_id, {
|
|
1155
1155
|
content_type: contentType,
|
|
1156
1156
|
reason: "No draft provided for required approval"
|
|
1157
1157
|
});
|
|
@@ -1169,7 +1169,7 @@ Create a draft first, then have it approved before publishing.`
|
|
|
1169
1169
|
if (draft.status !== "in_review") {
|
|
1170
1170
|
draft.status = "in_review";
|
|
1171
1171
|
const issue = await ctx.issues.create({
|
|
1172
|
-
companyId:
|
|
1172
|
+
companyId: config2.company_id,
|
|
1173
1173
|
title: `Review draft: ${draft.text.slice(0, 60)}`,
|
|
1174
1174
|
description: `Draft ID: ${draftId}
|
|
1175
1175
|
Format: ${draft.format}
|
|
@@ -1177,7 +1177,7 @@ Format: ${draft.format}
|
|
|
1177
1177
|
Text:
|
|
1178
1178
|
${draft.text}${draft.thread_tweets ? "\n\nThread:\n" + draft.thread_tweets.join("\n---\n") : ""}`
|
|
1179
1179
|
});
|
|
1180
|
-
await ctx.issues.update(issue.id, { status: "todo" },
|
|
1180
|
+
await ctx.issues.update(issue.id, { status: "todo" }, config2.company_id);
|
|
1181
1181
|
draft.review_issue_id = issue.id;
|
|
1182
1182
|
await ctx.entities.upsert({
|
|
1183
1183
|
entityType: ENTITY_TYPES.draft,
|
|
@@ -1186,7 +1186,7 @@ ${draft.text}${draft.thread_tweets ? "\n\nThread:\n" + draft.thread_tweets.join(
|
|
|
1186
1186
|
title: entity.title ?? draft.text.slice(0, 60),
|
|
1187
1187
|
data: draft
|
|
1188
1188
|
});
|
|
1189
|
-
await ctx.events.emit(EVENT_NAMES.approvalRequired,
|
|
1189
|
+
await ctx.events.emit(EVENT_NAMES.approvalRequired, config2.company_id, {
|
|
1190
1190
|
draft_id: draftId,
|
|
1191
1191
|
content_type: contentType,
|
|
1192
1192
|
reason: "Draft submitted for review"
|
|
@@ -1214,6 +1214,7 @@ async function publishThread(ctx, token, handle, tweets, metadata, companyId) {
|
|
|
1214
1214
|
replyTo = result.data.id;
|
|
1215
1215
|
const published = {
|
|
1216
1216
|
tweet_id: result.data.id,
|
|
1217
|
+
account: handle,
|
|
1217
1218
|
text: result.data.text,
|
|
1218
1219
|
published_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1219
1220
|
format: "thread",
|
|
@@ -1263,13 +1264,13 @@ async function getConfig(ctx) {
|
|
|
1263
1264
|
const raw = await ctx.config.get();
|
|
1264
1265
|
return { ...DEFAULT_CONFIG, ...raw };
|
|
1265
1266
|
}
|
|
1266
|
-
function resolveAccount(
|
|
1267
|
-
const accounts =
|
|
1267
|
+
function resolveAccount(config2, handle) {
|
|
1268
|
+
const accounts = config2.accounts || {};
|
|
1268
1269
|
const handles = Object.keys(accounts);
|
|
1269
1270
|
if (handles.length === 0) {
|
|
1270
1271
|
return { ok: false, error: "No accounts configured." };
|
|
1271
1272
|
}
|
|
1272
|
-
const target = handle ||
|
|
1273
|
+
const target = handle || config2.default_account || handles[0];
|
|
1273
1274
|
const account = accounts[target];
|
|
1274
1275
|
if (!account) {
|
|
1275
1276
|
return { ok: false, error: `Account @${target} not found in config. Available: ${handles.join(", ")}` };
|
|
@@ -1284,8 +1285,8 @@ function findEntityById(entities, id) {
|
|
|
1284
1285
|
async function handleSetupOauth(ctx, params) {
|
|
1285
1286
|
const handle = params.account;
|
|
1286
1287
|
if (!handle) return { error: "account param is required (X handle to store tokens for)." };
|
|
1287
|
-
const
|
|
1288
|
-
const resolved = resolveAccount(
|
|
1288
|
+
const config2 = await getConfig(ctx);
|
|
1289
|
+
const resolved = resolveAccount(config2, handle);
|
|
1289
1290
|
if (!resolved.ok) return { error: resolved.error };
|
|
1290
1291
|
const accessToken = params.access_token;
|
|
1291
1292
|
const refreshToken = params.refresh_token;
|
|
@@ -1303,12 +1304,13 @@ async function handleDraftPost(ctx, params) {
|
|
|
1303
1304
|
if (text.length > 280) {
|
|
1304
1305
|
return { error: `Tweet text exceeds 280 characters (${text.length}).` };
|
|
1305
1306
|
}
|
|
1306
|
-
const
|
|
1307
|
+
const config2 = await getConfig(ctx);
|
|
1307
1308
|
const format = params.format || "single";
|
|
1308
1309
|
const metadata = params.metadata || {};
|
|
1309
1310
|
const draft = {
|
|
1310
1311
|
text,
|
|
1311
1312
|
format,
|
|
1313
|
+
account: params.account || config2.default_account || void 0,
|
|
1312
1314
|
reply_to_tweet_id: params.reply_to_tweet_id,
|
|
1313
1315
|
quote_tweet_id: params.quote_tweet_id,
|
|
1314
1316
|
schedule_at: params.schedule_at,
|
|
@@ -1321,7 +1323,7 @@ async function handleDraftPost(ctx, params) {
|
|
|
1321
1323
|
title: text.slice(0, 60),
|
|
1322
1324
|
data: draft
|
|
1323
1325
|
});
|
|
1324
|
-
await ctx.events.emit(EVENT_NAMES.draftCreated,
|
|
1326
|
+
await ctx.events.emit(EVENT_NAMES.draftCreated, config2.company_id, {
|
|
1325
1327
|
draft_id: entity.id,
|
|
1326
1328
|
format,
|
|
1327
1329
|
metadata
|
|
@@ -1338,11 +1340,12 @@ async function handleDraftThread(ctx, params) {
|
|
|
1338
1340
|
return { error: `Tweet ${i + 1} exceeds 280 characters (${threadTweets[i].length}).` };
|
|
1339
1341
|
}
|
|
1340
1342
|
}
|
|
1341
|
-
const
|
|
1343
|
+
const config2 = await getConfig(ctx);
|
|
1342
1344
|
const metadata = params.metadata || {};
|
|
1343
1345
|
const draft = {
|
|
1344
1346
|
text: threadTweets[0],
|
|
1345
1347
|
format: "thread",
|
|
1348
|
+
account: params.account || config2.default_account || void 0,
|
|
1346
1349
|
thread_tweets: threadTweets,
|
|
1347
1350
|
schedule_at: params.schedule_at,
|
|
1348
1351
|
status: "draft",
|
|
@@ -1354,7 +1357,7 @@ async function handleDraftThread(ctx, params) {
|
|
|
1354
1357
|
title: `Thread: ${threadTweets[0].slice(0, 50)}`,
|
|
1355
1358
|
data: draft
|
|
1356
1359
|
});
|
|
1357
|
-
await ctx.events.emit(EVENT_NAMES.draftCreated,
|
|
1360
|
+
await ctx.events.emit(EVENT_NAMES.draftCreated, config2.company_id, {
|
|
1358
1361
|
draft_id: entity.id,
|
|
1359
1362
|
format: "thread",
|
|
1360
1363
|
metadata
|
|
@@ -1382,8 +1385,8 @@ async function handleUpdateDraft(ctx, params) {
|
|
|
1382
1385
|
return { content: JSON.stringify({ draft_id: draftId, status: "draft", updated: true }) };
|
|
1383
1386
|
}
|
|
1384
1387
|
async function handlePublishPost(ctx, params) {
|
|
1385
|
-
const
|
|
1386
|
-
const resolved = resolveAccount(
|
|
1388
|
+
const config2 = await getConfig(ctx);
|
|
1389
|
+
const resolved = resolveAccount(config2, params.account);
|
|
1387
1390
|
if (!resolved.ok) return { error: resolved.error };
|
|
1388
1391
|
const { handle, account } = resolved;
|
|
1389
1392
|
let text = params.text;
|
|
@@ -1397,13 +1400,14 @@ async function handlePublishPost(ctx, params) {
|
|
|
1397
1400
|
metadata = { ...match.data.metadata, ...metadata };
|
|
1398
1401
|
}
|
|
1399
1402
|
if (!text) return { error: "No text provided and no draft_id." };
|
|
1400
|
-
const approval = await checkApproval(ctx,
|
|
1403
|
+
const approval = await checkApproval(ctx, config2, "posts", draftId, account.approval_modes);
|
|
1401
1404
|
if (!approval.allowed) return { error: `Blocked: ${approval.reason}` };
|
|
1402
|
-
const token = await getValidAccessToken(ctx,
|
|
1405
|
+
const token = await getValidAccessToken(ctx, config2, handle);
|
|
1403
1406
|
const result = await createTweet(ctx.http, token, { text });
|
|
1404
1407
|
await updateRateLimits(ctx, handle, "post_tweets", result.rateLimit);
|
|
1405
1408
|
const published = {
|
|
1406
1409
|
tweet_id: result.data.id,
|
|
1410
|
+
account: handle,
|
|
1407
1411
|
text: result.data.text,
|
|
1408
1412
|
published_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1409
1413
|
draft_id: draftId,
|
|
@@ -1417,7 +1421,7 @@ async function handlePublishPost(ctx, params) {
|
|
|
1417
1421
|
title: text.slice(0, 60),
|
|
1418
1422
|
data: published
|
|
1419
1423
|
});
|
|
1420
|
-
await ctx.events.emit(EVENT_NAMES.postPublished,
|
|
1424
|
+
await ctx.events.emit(EVENT_NAMES.postPublished, config2.company_id, {
|
|
1421
1425
|
tweet_id: result.data.id,
|
|
1422
1426
|
text,
|
|
1423
1427
|
format: "single",
|
|
@@ -1426,20 +1430,21 @@ async function handlePublishPost(ctx, params) {
|
|
|
1426
1430
|
return { content: JSON.stringify({ tweet_id: result.data.id, text: result.data.text, status: "published" }) };
|
|
1427
1431
|
}
|
|
1428
1432
|
async function handleReplyToTweet(ctx, params) {
|
|
1429
|
-
const
|
|
1430
|
-
const resolved = resolveAccount(
|
|
1433
|
+
const config2 = await getConfig(ctx);
|
|
1434
|
+
const resolved = resolveAccount(config2, params.account);
|
|
1431
1435
|
if (!resolved.ok) return { error: resolved.error };
|
|
1432
1436
|
const { handle, account } = resolved;
|
|
1433
1437
|
const tweetId = params.tweet_id;
|
|
1434
1438
|
const text = params.text;
|
|
1435
1439
|
const metadata = params.metadata || {};
|
|
1436
|
-
const approval = await checkApproval(ctx,
|
|
1440
|
+
const approval = await checkApproval(ctx, config2, "replies", params.draft_id, account.approval_modes);
|
|
1437
1441
|
if (!approval.allowed) return { error: `Blocked: ${approval.reason}` };
|
|
1438
|
-
const token = await getValidAccessToken(ctx,
|
|
1442
|
+
const token = await getValidAccessToken(ctx, config2, handle);
|
|
1439
1443
|
const result = await createTweet(ctx.http, token, { text, reply_to: tweetId });
|
|
1440
1444
|
await updateRateLimits(ctx, handle, "post_tweets", result.rateLimit);
|
|
1441
1445
|
const published = {
|
|
1442
1446
|
tweet_id: result.data.id,
|
|
1447
|
+
account: handle,
|
|
1443
1448
|
text: result.data.text,
|
|
1444
1449
|
published_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1445
1450
|
draft_id: params.draft_id,
|
|
@@ -1453,7 +1458,7 @@ async function handleReplyToTweet(ctx, params) {
|
|
|
1453
1458
|
title: `Reply: ${text.slice(0, 50)}`,
|
|
1454
1459
|
data: published
|
|
1455
1460
|
});
|
|
1456
|
-
await ctx.events.emit(EVENT_NAMES.postPublished,
|
|
1461
|
+
await ctx.events.emit(EVENT_NAMES.postPublished, config2.company_id, {
|
|
1457
1462
|
tweet_id: result.data.id,
|
|
1458
1463
|
text,
|
|
1459
1464
|
format: "reply",
|
|
@@ -1462,20 +1467,21 @@ async function handleReplyToTweet(ctx, params) {
|
|
|
1462
1467
|
return { content: JSON.stringify({ tweet_id: result.data.id, text: result.data.text, status: "published", reply_to: tweetId }) };
|
|
1463
1468
|
}
|
|
1464
1469
|
async function handleQuoteTweet(ctx, params) {
|
|
1465
|
-
const
|
|
1466
|
-
const resolved = resolveAccount(
|
|
1470
|
+
const config2 = await getConfig(ctx);
|
|
1471
|
+
const resolved = resolveAccount(config2, params.account);
|
|
1467
1472
|
if (!resolved.ok) return { error: resolved.error };
|
|
1468
1473
|
const { handle, account } = resolved;
|
|
1469
1474
|
const tweetId = params.tweet_id;
|
|
1470
1475
|
const text = params.text;
|
|
1471
1476
|
const metadata = params.metadata || {};
|
|
1472
|
-
const approval = await checkApproval(ctx,
|
|
1477
|
+
const approval = await checkApproval(ctx, config2, "quotes", params.draft_id, account.approval_modes);
|
|
1473
1478
|
if (!approval.allowed) return { error: `Blocked: ${approval.reason}` };
|
|
1474
|
-
const token = await getValidAccessToken(ctx,
|
|
1479
|
+
const token = await getValidAccessToken(ctx, config2, handle);
|
|
1475
1480
|
const result = await createTweet(ctx.http, token, { text, quote_tweet_id: tweetId });
|
|
1476
1481
|
await updateRateLimits(ctx, handle, "post_tweets", result.rateLimit);
|
|
1477
1482
|
const published = {
|
|
1478
1483
|
tweet_id: result.data.id,
|
|
1484
|
+
account: handle,
|
|
1479
1485
|
text: result.data.text,
|
|
1480
1486
|
published_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1481
1487
|
draft_id: params.draft_id,
|
|
@@ -1489,7 +1495,7 @@ async function handleQuoteTweet(ctx, params) {
|
|
|
1489
1495
|
title: `Quote: ${text.slice(0, 50)}`,
|
|
1490
1496
|
data: published
|
|
1491
1497
|
});
|
|
1492
|
-
await ctx.events.emit(EVENT_NAMES.postPublished,
|
|
1498
|
+
await ctx.events.emit(EVENT_NAMES.postPublished, config2.company_id, {
|
|
1493
1499
|
tweet_id: result.data.id,
|
|
1494
1500
|
text,
|
|
1495
1501
|
format: "quote",
|
|
@@ -1498,18 +1504,19 @@ async function handleQuoteTweet(ctx, params) {
|
|
|
1498
1504
|
return { content: JSON.stringify({ tweet_id: result.data.id, text: result.data.text, status: "published", quoted: tweetId }) };
|
|
1499
1505
|
}
|
|
1500
1506
|
async function handleRepost(ctx, params) {
|
|
1501
|
-
const
|
|
1502
|
-
const resolved = resolveAccount(
|
|
1507
|
+
const config2 = await getConfig(ctx);
|
|
1508
|
+
const resolved = resolveAccount(config2, params.account);
|
|
1503
1509
|
if (!resolved.ok) return { error: resolved.error };
|
|
1504
1510
|
const { handle, account } = resolved;
|
|
1505
1511
|
const tweetId = params.tweet_id;
|
|
1506
|
-
const approval = await checkApproval(ctx,
|
|
1512
|
+
const approval = await checkApproval(ctx, config2, "reposts", params.draft_id, account.approval_modes);
|
|
1507
1513
|
if (!approval.allowed) return { error: `Blocked: ${approval.reason}` };
|
|
1508
|
-
const token = await getValidAccessToken(ctx,
|
|
1514
|
+
const token = await getValidAccessToken(ctx, config2, handle);
|
|
1509
1515
|
const result = await repost(ctx.http, token, account.x_user_id, tweetId);
|
|
1510
1516
|
await updateRateLimits(ctx, handle, "retweets", result.rateLimit);
|
|
1511
1517
|
const published = {
|
|
1512
1518
|
tweet_id: tweetId,
|
|
1519
|
+
account: handle,
|
|
1513
1520
|
text: "",
|
|
1514
1521
|
published_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1515
1522
|
draft_id: params.draft_id,
|
|
@@ -1523,7 +1530,7 @@ async function handleRepost(ctx, params) {
|
|
|
1523
1530
|
title: `Repost: ${tweetId}`,
|
|
1524
1531
|
data: published
|
|
1525
1532
|
});
|
|
1526
|
-
await ctx.events.emit(EVENT_NAMES.postPublished,
|
|
1533
|
+
await ctx.events.emit(EVENT_NAMES.postPublished, config2.company_id, {
|
|
1527
1534
|
tweet_id: tweetId,
|
|
1528
1535
|
text: "",
|
|
1529
1536
|
format: "repost",
|
|
@@ -1554,6 +1561,7 @@ async function handleSchedulePost(ctx, params) {
|
|
|
1554
1561
|
const draft = {
|
|
1555
1562
|
text,
|
|
1556
1563
|
format: "single",
|
|
1564
|
+
account: params.account || config.default_account || void 0,
|
|
1557
1565
|
schedule_at: scheduleAt,
|
|
1558
1566
|
status: "draft",
|
|
1559
1567
|
metadata
|
|
@@ -1567,8 +1575,8 @@ async function handleSchedulePost(ctx, params) {
|
|
|
1567
1575
|
return { content: JSON.stringify({ draft_id: entity.id, schedule_at: scheduleAt, status: "scheduled" }) };
|
|
1568
1576
|
}
|
|
1569
1577
|
async function handlePublishThread(ctx, params) {
|
|
1570
|
-
const
|
|
1571
|
-
const resolved = resolveAccount(
|
|
1578
|
+
const config2 = await getConfig(ctx);
|
|
1579
|
+
const resolved = resolveAccount(config2, params.account);
|
|
1572
1580
|
if (!resolved.ok) return { error: resolved.error };
|
|
1573
1581
|
const { handle, account } = resolved;
|
|
1574
1582
|
let threadTweets = params.thread_tweets;
|
|
@@ -1584,17 +1592,17 @@ async function handlePublishThread(ctx, params) {
|
|
|
1584
1592
|
if (!threadTweets || threadTweets.length < 2) {
|
|
1585
1593
|
return { error: "Thread must have at least 2 tweets." };
|
|
1586
1594
|
}
|
|
1587
|
-
const approval = await checkApproval(ctx,
|
|
1595
|
+
const approval = await checkApproval(ctx, config2, "posts", draftId, account.approval_modes);
|
|
1588
1596
|
if (!approval.allowed) return { error: `Blocked: ${approval.reason}` };
|
|
1589
|
-
const token = await getValidAccessToken(ctx,
|
|
1590
|
-
const result = await publishThread(ctx, token, handle, threadTweets, metadata,
|
|
1591
|
-
await ctx.events.emit(EVENT_NAMES.threadPublished,
|
|
1597
|
+
const token = await getValidAccessToken(ctx, config2, handle);
|
|
1598
|
+
const result = await publishThread(ctx, token, handle, threadTweets, metadata, config2.company_id);
|
|
1599
|
+
await ctx.events.emit(EVENT_NAMES.threadPublished, config2.company_id, {
|
|
1592
1600
|
tweet_ids: result.tweetIds,
|
|
1593
1601
|
thread_length: threadTweets.length,
|
|
1594
1602
|
partial: result.partial
|
|
1595
1603
|
});
|
|
1596
1604
|
for (const tweetId of result.tweetIds) {
|
|
1597
|
-
await ctx.events.emit(EVENT_NAMES.postPublished,
|
|
1605
|
+
await ctx.events.emit(EVENT_NAMES.postPublished, config2.company_id, {
|
|
1598
1606
|
tweet_id: tweetId,
|
|
1599
1607
|
text: "",
|
|
1600
1608
|
format: "thread",
|
|
@@ -1640,8 +1648,8 @@ async function handleGetPostMetrics(ctx, params) {
|
|
|
1640
1648
|
}) };
|
|
1641
1649
|
}
|
|
1642
1650
|
async function handleGetAccountStatus(ctx, params) {
|
|
1643
|
-
const
|
|
1644
|
-
const accounts =
|
|
1651
|
+
const config2 = await getConfig(ctx);
|
|
1652
|
+
const accounts = config2.accounts || {};
|
|
1645
1653
|
const handles = params.account ? [params.account] : Object.keys(accounts);
|
|
1646
1654
|
const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
1647
1655
|
const entities = await ctx.entities.list({ entityType: ENTITY_TYPES.publishedPost, limit: 500 });
|
|
@@ -1667,29 +1675,29 @@ async function handleGetAccountStatus(ctx, params) {
|
|
|
1667
1675
|
}
|
|
1668
1676
|
const todayCount = entities.filter((e) => {
|
|
1669
1677
|
const data = e.data;
|
|
1670
|
-
return data.published_at.startsWith(today);
|
|
1678
|
+
return data.published_at.startsWith(today) && (!data.account || data.account === handle);
|
|
1671
1679
|
}).length;
|
|
1672
1680
|
statuses.push({
|
|
1673
1681
|
x_handle: handle,
|
|
1674
1682
|
role: accounts[handle]?.role || "unknown",
|
|
1675
1683
|
token_health: tokenHealth,
|
|
1676
|
-
daily_posts: { count: todayCount, limit:
|
|
1684
|
+
daily_posts: { count: todayCount, limit: config2.daily_post_limit },
|
|
1677
1685
|
rate_limits: rateLimits
|
|
1678
1686
|
});
|
|
1679
1687
|
}
|
|
1680
1688
|
return { content: JSON.stringify(handles.length === 1 ? statuses[0] : statuses) };
|
|
1681
1689
|
}
|
|
1682
1690
|
async function handleTokenRefresh(ctx, _job) {
|
|
1683
|
-
const
|
|
1684
|
-
const handles = Object.keys(
|
|
1691
|
+
const config2 = await getConfig(ctx);
|
|
1692
|
+
const handles = Object.keys(config2.accounts || {});
|
|
1685
1693
|
for (const handle of handles) {
|
|
1686
1694
|
try {
|
|
1687
|
-
await refreshTokens(ctx,
|
|
1695
|
+
await refreshTokens(ctx, config2, handle);
|
|
1688
1696
|
ctx.logger.info(`Token refresh succeeded for @${handle}`);
|
|
1689
1697
|
} catch (err) {
|
|
1690
1698
|
ctx.logger.error(`Token refresh failed for @${handle}`, { error: String(err) });
|
|
1691
1699
|
const issue = await ctx.issues.create({
|
|
1692
|
-
companyId:
|
|
1700
|
+
companyId: config2.company_id,
|
|
1693
1701
|
title: `OAuth token refresh failed for @${handle}`,
|
|
1694
1702
|
description: `Token refresh failed for @${handle} at ${(/* @__PURE__ */ new Date()).toISOString()}.
|
|
1695
1703
|
|
|
@@ -1697,18 +1705,12 @@ Error: ${String(err)}
|
|
|
1697
1705
|
|
|
1698
1706
|
Manual re-auth may be required via setup-oauth tool.`
|
|
1699
1707
|
});
|
|
1700
|
-
await ctx.issues.update(issue.id, { status: "todo" },
|
|
1708
|
+
await ctx.issues.update(issue.id, { status: "todo" }, config2.company_id);
|
|
1701
1709
|
}
|
|
1702
1710
|
}
|
|
1703
1711
|
}
|
|
1704
1712
|
async function handlePublishScheduled(ctx, _job) {
|
|
1705
|
-
const
|
|
1706
|
-
const resolved = resolveAccount(config);
|
|
1707
|
-
if (!resolved.ok) {
|
|
1708
|
-
ctx.logger.error(resolved.error);
|
|
1709
|
-
return;
|
|
1710
|
-
}
|
|
1711
|
-
const { handle } = resolved;
|
|
1713
|
+
const config2 = await getConfig(ctx);
|
|
1712
1714
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1713
1715
|
const entities = await ctx.entities.list({ entityType: ENTITY_TYPES.draft, limit: 100 });
|
|
1714
1716
|
const due = entities.filter((e) => {
|
|
@@ -1717,15 +1719,21 @@ async function handlePublishScheduled(ctx, _job) {
|
|
|
1717
1719
|
});
|
|
1718
1720
|
for (const entity of due) {
|
|
1719
1721
|
const draft = entity.data;
|
|
1720
|
-
const
|
|
1722
|
+
const resolved = resolveAccount(config2, draft.account);
|
|
1723
|
+
if (!resolved.ok) {
|
|
1724
|
+
ctx.logger.error(`Scheduled draft ${entity.id}: ${resolved.error}`);
|
|
1725
|
+
continue;
|
|
1726
|
+
}
|
|
1727
|
+
const { handle, account } = resolved;
|
|
1728
|
+
const approval = await checkApproval(ctx, config2, "scheduled", entity.id, account.approval_modes);
|
|
1721
1729
|
if (!approval.allowed) {
|
|
1722
1730
|
ctx.logger.info(`Scheduled draft ${entity.id} blocked: ${approval.reason}`);
|
|
1723
1731
|
continue;
|
|
1724
1732
|
}
|
|
1725
1733
|
try {
|
|
1726
|
-
const token = await getValidAccessToken(ctx,
|
|
1734
|
+
const token = await getValidAccessToken(ctx, config2, handle);
|
|
1727
1735
|
if (draft.format === "thread" && draft.thread_tweets) {
|
|
1728
|
-
await publishThread(ctx, token, draft.thread_tweets, draft.metadata,
|
|
1736
|
+
await publishThread(ctx, token, handle, draft.thread_tweets, draft.metadata, config2.company_id);
|
|
1729
1737
|
} else {
|
|
1730
1738
|
const result = await createTweet(ctx.http, token, {
|
|
1731
1739
|
text: draft.text,
|
|
@@ -1740,6 +1748,7 @@ async function handlePublishScheduled(ctx, _job) {
|
|
|
1740
1748
|
title: draft.text.slice(0, 60),
|
|
1741
1749
|
data: {
|
|
1742
1750
|
tweet_id: result.data.id,
|
|
1751
|
+
account: handle,
|
|
1743
1752
|
text: result.data.text,
|
|
1744
1753
|
published_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1745
1754
|
draft_id: entity.id,
|
|
@@ -1747,7 +1756,7 @@ async function handlePublishScheduled(ctx, _job) {
|
|
|
1747
1756
|
metadata: draft.metadata
|
|
1748
1757
|
}
|
|
1749
1758
|
});
|
|
1750
|
-
await ctx.events.emit(EVENT_NAMES.postPublished,
|
|
1759
|
+
await ctx.events.emit(EVENT_NAMES.postPublished, config2.company_id, {
|
|
1751
1760
|
tweet_id: result.data.id,
|
|
1752
1761
|
text: draft.text,
|
|
1753
1762
|
format: draft.format,
|
|
@@ -1769,14 +1778,14 @@ async function handlePublishScheduled(ctx, _job) {
|
|
|
1769
1778
|
}
|
|
1770
1779
|
}
|
|
1771
1780
|
async function handleMetricsCapture(ctx, _job) {
|
|
1772
|
-
const
|
|
1773
|
-
const resolved = resolveAccount(
|
|
1781
|
+
const config2 = await getConfig(ctx);
|
|
1782
|
+
const resolved = resolveAccount(config2);
|
|
1774
1783
|
if (!resolved.ok) {
|
|
1775
1784
|
ctx.logger.error(resolved.error);
|
|
1776
1785
|
return;
|
|
1777
1786
|
}
|
|
1778
1787
|
const { handle } = resolved;
|
|
1779
|
-
const lookbackMs =
|
|
1788
|
+
const lookbackMs = config2.metrics_capture_lookback_days * 864e5;
|
|
1780
1789
|
const cutoff = new Date(Date.now() - lookbackMs).toISOString();
|
|
1781
1790
|
const entities = await ctx.entities.list({ entityType: ENTITY_TYPES.publishedPost, limit: 500 });
|
|
1782
1791
|
const recent = entities.filter((e) => {
|
|
@@ -1785,7 +1794,7 @@ async function handleMetricsCapture(ctx, _job) {
|
|
|
1785
1794
|
});
|
|
1786
1795
|
if (recent.length === 0) return;
|
|
1787
1796
|
const tweetIds = recent.map((e) => e.data.tweet_id);
|
|
1788
|
-
const token = await getValidAccessToken(ctx,
|
|
1797
|
+
const token = await getValidAccessToken(ctx, config2, handle);
|
|
1789
1798
|
const batchSize = 100;
|
|
1790
1799
|
for (let i = 0; i < tweetIds.length; i += batchSize) {
|
|
1791
1800
|
const batch = tweetIds.slice(i, i + batchSize);
|
|
@@ -1812,9 +1821,9 @@ async function handleMetricsCapture(ctx, _job) {
|
|
|
1812
1821
|
};
|
|
1813
1822
|
const totalEngagement = newMetrics.likes + newMetrics.retweets + newMetrics.replies;
|
|
1814
1823
|
const prevTotal = data.metrics ? data.metrics.likes + data.metrics.retweets + data.metrics.replies : 0;
|
|
1815
|
-
for (const milestone of
|
|
1824
|
+
for (const milestone of config2.engagement_milestones) {
|
|
1816
1825
|
if (totalEngagement >= milestone && prevTotal < milestone) {
|
|
1817
|
-
await ctx.events.emit(EVENT_NAMES.postEngagementMilestone,
|
|
1826
|
+
await ctx.events.emit(EVENT_NAMES.postEngagementMilestone, config2.company_id, {
|
|
1818
1827
|
tweet_id: tweet.id,
|
|
1819
1828
|
milestone,
|
|
1820
1829
|
current_metrics: newMetrics
|
|
@@ -1935,8 +1944,8 @@ var plugin = definePlugin({
|
|
|
1935
1944
|
(params) => handleGetAccountStatus(ctx, p(params))
|
|
1936
1945
|
);
|
|
1937
1946
|
ctx.data.register("dashboard-summary", async () => {
|
|
1938
|
-
const
|
|
1939
|
-
const accounts =
|
|
1947
|
+
const config2 = await getConfig(ctx);
|
|
1948
|
+
const accounts = config2.accounts || {};
|
|
1940
1949
|
const handles = Object.keys(accounts);
|
|
1941
1950
|
const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
1942
1951
|
const published = await ctx.entities.list({ entityType: ENTITY_TYPES.publishedPost, limit: 100 });
|
|
@@ -1962,7 +1971,7 @@ var plugin = definePlugin({
|
|
|
1962
1971
|
const recentPosts = published.map((e) => e.data).sort((a, b) => a.published_at > b.published_at ? -1 : 1).slice(0, 5);
|
|
1963
1972
|
return {
|
|
1964
1973
|
today_post_count: todayPosts.length,
|
|
1965
|
-
daily_limit:
|
|
1974
|
+
daily_limit: config2.daily_post_limit,
|
|
1966
1975
|
pending_drafts: pendingDrafts.length,
|
|
1967
1976
|
token_health: tokenHealth,
|
|
1968
1977
|
accounts: accountHealth,
|
|
@@ -1970,8 +1979,8 @@ var plugin = definePlugin({
|
|
|
1970
1979
|
};
|
|
1971
1980
|
});
|
|
1972
1981
|
ctx.data.register("plugin-config", async () => {
|
|
1973
|
-
const
|
|
1974
|
-
return
|
|
1982
|
+
const config2 = await getConfig(ctx);
|
|
1983
|
+
return config2;
|
|
1975
1984
|
});
|
|
1976
1985
|
ctx.data.register("content-queue", async () => {
|
|
1977
1986
|
const allDrafts = await ctx.entities.list({ entityType: ENTITY_TYPES.draft, limit: 100 });
|
|
@@ -1991,8 +2000,8 @@ var plugin = definePlugin({
|
|
|
1991
2000
|
},
|
|
1992
2001
|
async onHealth() {
|
|
1993
2002
|
if (!pluginCtx) return { status: "error", message: "Plugin not initialized" };
|
|
1994
|
-
const
|
|
1995
|
-
const accounts =
|
|
2003
|
+
const config2 = await getConfig(pluginCtx);
|
|
2004
|
+
const accounts = config2.accounts || {};
|
|
1996
2005
|
const handles = Object.keys(accounts);
|
|
1997
2006
|
if (handles.length === 0) {
|
|
1998
2007
|
return { status: "error", message: "No accounts configured" };
|
|
@@ -2033,15 +2042,15 @@ var plugin = definePlugin({
|
|
|
2033
2042
|
const message = issues.length > 0 ? issues.join("; ") : `All ${handles.length} account(s) operational`;
|
|
2034
2043
|
return { status, message, details: { accounts: accountDetails } };
|
|
2035
2044
|
},
|
|
2036
|
-
async onValidateConfig(
|
|
2045
|
+
async onValidateConfig(config2) {
|
|
2037
2046
|
const warnings = [];
|
|
2038
2047
|
const errors = [];
|
|
2039
|
-
const accounts =
|
|
2048
|
+
const accounts = config2.accounts || {};
|
|
2040
2049
|
const handles = Object.keys(accounts);
|
|
2041
2050
|
if (handles.length === 0) {
|
|
2042
2051
|
errors.push("At least one account is required in accounts map");
|
|
2043
2052
|
}
|
|
2044
|
-
const defaultAcct =
|
|
2053
|
+
const defaultAcct = config2.default_account;
|
|
2045
2054
|
if (defaultAcct && handles.length > 0 && !accounts[defaultAcct]) {
|
|
2046
2055
|
errors.push(`default_account "${defaultAcct}" is not in the accounts map. Available: ${handles.join(", ")}`);
|
|
2047
2056
|
}
|
|
@@ -2051,8 +2060,8 @@ var plugin = definePlugin({
|
|
|
2051
2060
|
if (!acct.x_user_id) errors.push(`Account ${handle}: x_user_id is required`);
|
|
2052
2061
|
}
|
|
2053
2062
|
if (pluginCtx) {
|
|
2054
|
-
const clientIdRef =
|
|
2055
|
-
const clientSecretRef =
|
|
2063
|
+
const clientIdRef = config2.oauth_client_id_ref || DEFAULT_CONFIG.oauth_client_id_ref;
|
|
2064
|
+
const clientSecretRef = config2.oauth_client_secret_ref || DEFAULT_CONFIG.oauth_client_secret_ref;
|
|
2056
2065
|
try {
|
|
2057
2066
|
await pluginCtx.secrets.resolve(clientIdRef);
|
|
2058
2067
|
} catch {
|
package/dist/worker.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../node_modules/.pnpm/@paperclipai+plugin-sdk@file+.paperclip-sdk+paperclipai-plugin-sdk-1.0.0.tgz_react@19.2.4/node_modules/@paperclipai/plugin-sdk/src/define-plugin.ts", "../node_modules/.pnpm/@paperclipai+plugin-sdk@file+.paperclip-sdk+paperclipai-plugin-sdk-1.0.0.tgz_react@19.2.4/node_modules/@paperclipai/plugin-sdk/src/worker-rpc-host.ts", "../node_modules/.pnpm/@paperclipai+plugin-sdk@file+.paperclip-sdk+paperclipai-plugin-sdk-1.0.0.tgz_react@19.2.4/node_modules/@paperclipai/plugin-sdk/src/protocol.ts", "../src/constants.ts", "../src/pipeline/oauth-manager.ts", "../src/pipeline/x-api-write-client.ts", "../src/pipeline/rate-limiter.ts", "../src/pipeline/approval-gate.ts", "../src/pipeline/thread-publisher.ts", "../src/worker.ts"],
|
|
4
|
-
"sourcesContent": [null, null, null, "export const PLUGIN_ID = \"peak6-labs.x-publishing\";\nexport const PLUGIN_VERSION = \"0.2.2\";\n\nexport const TOOL_NAMES = {\n draftPost: \"draft-post\",\n updateDraft: \"update-draft\",\n publishPost: \"publish-post\",\n replyToTweet: \"reply-to-tweet\",\n quoteTweet: \"quote-tweet\",\n repost: \"repost\",\n schedulePost: \"schedule-post\",\n publishThread: \"publish-thread\",\n draftThread: \"draft-thread\",\n getDrafts: \"get-drafts\",\n getSchedule: \"get-schedule\",\n getPostMetrics: \"get-post-metrics\",\n getAccountStatus: \"get-account-status\",\n setupOauth: \"setup-oauth\",\n} as const;\n\nexport const JOB_KEYS = {\n tokenRefresh: \"token-refresh\",\n publishScheduled: \"publish-scheduled\",\n metricsCapture: \"metrics-capture\",\n staleDraftCleanup: \"stale-draft-cleanup\",\n} as const;\n\nexport const ENTITY_TYPES = {\n draft: \"draft\",\n publishedPost: \"published-post\",\n} as const;\n\nexport const EVENT_NAMES = {\n postPublished: \"post.published\",\n draftCreated: \"draft.created\",\n approvalRequired: \"approval.required\",\n postEngagementMilestone: \"post.engagement-milestone\",\n threadPublished: \"thread.published\",\n} as const;\n\nexport const STATE_KEYS = {\n oauthTokens: \"oauth_tokens\",\n rateLimits: \"rate_limits\",\n} as const;\n\nexport const SLOT_IDS = {\n dashboardWidget: \"x-publishing-dashboard\",\n settingsPage: \"x-publishing-settings\",\n contentPage: \"x-publishing-content\",\n} as const;\n\nexport const EXPORT_NAMES = {\n dashboardWidget: \"DashboardWidget\",\n settingsPage: \"SettingsPage\",\n contentPage: \"ContentPage\",\n} as const;\n\nexport type ApprovalMode = \"required\" | \"optional\" | \"none\";\n\nexport const DEFAULT_APPROVAL_MODES = {\n posts: \"none\" as ApprovalMode,\n replies: \"none\" as ApprovalMode,\n quotes: \"none\" as ApprovalMode,\n reposts: \"none\" as ApprovalMode,\n scheduled: \"required\" as ApprovalMode,\n};\n\nexport const DEFAULT_CONFIG = {\n company_id: \"\",\n oauth_client_id_ref: \"X_OAUTH_CLIENT_ID\",\n oauth_client_secret_ref: \"X_OAUTH_CLIENT_SECRET\",\n default_account: \"\",\n accounts: {} as Record<string, { x_handle: string; x_user_id: string; role: \"hub\" | \"spoke\"; approval_modes: typeof DEFAULT_APPROVAL_MODES }>,\n daily_post_limit: 25,\n engagement_milestones: [50, 100, 500, 1000],\n metrics_capture_lookback_days: 7,\n alert_agents: [] as Array<{ agentId: string; memoryFile: string | null }>,\n} as const;\n\n/** Build per-account state key */\nexport function accountStateKey(base: string, handle: string): string {\n return `${base}:${handle}`;\n}\n", "import type { PluginContext } from \"@paperclipai/plugin-sdk\";\nimport { STATE_KEYS, accountStateKey } from \"../constants.js\";\nimport type { PublishingConfig, TokenState } from \"../types.js\";\n\nconst REFRESH_BUFFER_MS = 5 * 60 * 1000; // 5 minutes\n\nfunction stateKey(key: string) {\n return { scopeKind: \"instance\" as const, stateKey: key };\n}\n\nexport async function getTokens(ctx: PluginContext, handle: string): Promise<TokenState> {\n const raw = await ctx.state.get(stateKey(accountStateKey(STATE_KEYS.oauthTokens, handle)));\n if (!raw) throw new Error(`No OAuth tokens in state for @${handle}`);\n return raw as unknown as TokenState;\n}\n\nexport async function setTokens(ctx: PluginContext, handle: string, tokens: TokenState): Promise<void> {\n await ctx.state.set(\n stateKey(accountStateKey(STATE_KEYS.oauthTokens, handle)),\n tokens as unknown as Record<string, unknown>,\n );\n}\n\nexport async function refreshTokens(ctx: PluginContext, config: PublishingConfig, handle: string): Promise<TokenState> {\n const current = await getTokens(ctx, handle);\n const clientId = await ctx.secrets.resolve(config.oauth_client_id_ref);\n const clientSecret = await ctx.secrets.resolve(config.oauth_client_secret_ref);\n\n const resp = await ctx.http.fetch(\"https://api.x.com/2/oauth2/token\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n Authorization: `Basic ${btoa(`${clientId}:${clientSecret}`)}`,\n },\n body: new URLSearchParams({\n grant_type: \"refresh_token\",\n refresh_token: current.refresh_token,\n }).toString(),\n });\n\n if (!resp.ok) {\n const text = await resp.text();\n throw new Error(`Token refresh failed for @${handle}: HTTP ${resp.status} \u2014 ${text}`);\n }\n\n const body = (await resp.json()) as {\n access_token: string;\n refresh_token: string;\n expires_in: number;\n token_type: string;\n };\n\n const newTokens: TokenState = {\n access_token: body.access_token,\n refresh_token: body.refresh_token,\n expires_at: Date.now() + body.expires_in * 1000,\n };\n\n await setTokens(ctx, handle, newTokens);\n return newTokens;\n}\n\nexport async function getValidAccessToken(ctx: PluginContext, config: PublishingConfig, handle: string): Promise<string> {\n const tokens = await getTokens(ctx, handle);\n\n if (tokens.expires_at - Date.now() < REFRESH_BUFFER_MS) {\n const refreshed = await refreshTokens(ctx, config, handle);\n return refreshed.access_token;\n }\n\n return tokens.access_token;\n}\n", "import type { PluginContext } from \"@paperclipai/plugin-sdk\";\nimport type { RateLimitHeaders } from \"../types.js\";\n\nfunction parseRateLimitHeaders(headers: Headers): RateLimitHeaders {\n const remaining = parseInt(headers.get(\"x-rate-limit-remaining\") || \"99\", 10);\n const resetEpoch = parseInt(headers.get(\"x-rate-limit-reset\") || \"0\", 10);\n return {\n remaining,\n reset_at: resetEpoch * 1000, // X API returns epoch seconds\n };\n}\n\nasync function withRetry<T>(fn: () => Promise<T>, maxRetries = 2): Promise<T> {\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n return await fn();\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n if (attempt < maxRetries && message.includes(\"429\")) {\n const backoffMs = Math.pow(2, attempt + 1) * 1000;\n await new Promise((r) => setTimeout(r, backoffMs));\n continue;\n }\n throw err;\n }\n }\n throw new Error(\"Unreachable\");\n}\n\ntype HttpClient = PluginContext[\"http\"];\n\nexport async function createTweet(\n http: HttpClient,\n token: string,\n params: { text: string; reply_to?: string; quote_tweet_id?: string; media_ids?: string[] },\n): Promise<{ data: { id: string; text: string }; rateLimit: RateLimitHeaders }> {\n return withRetry(async () => {\n const body: Record<string, unknown> = { text: params.text };\n\n if (params.reply_to) {\n body.reply = { in_reply_to_tweet_id: params.reply_to };\n }\n if (params.quote_tweet_id) {\n body.quote_tweet_id = params.quote_tweet_id;\n }\n if (params.media_ids && params.media_ids.length > 0) {\n body.media = { media_ids: params.media_ids };\n }\n\n const resp = await http.fetch(\"https://api.x.com/2/tweets\", {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(body),\n });\n\n if (resp.status === 429) {\n throw new Error(\"429 Rate limited\");\n }\n\n if (resp.status !== 201) {\n const text = await resp.text();\n throw new Error(`Create tweet failed: HTTP ${resp.status} \u2014 ${text}`);\n }\n\n const json = (await resp.json()) as { data: { id: string; text: string } };\n return {\n data: json.data,\n rateLimit: parseRateLimitHeaders(resp.headers),\n };\n });\n}\n\nexport async function deleteTweet(\n http: HttpClient,\n token: string,\n tweetId: string,\n): Promise<{ data: { deleted: boolean }; rateLimit: RateLimitHeaders }> {\n return withRetry(async () => {\n const resp = await http.fetch(`https://api.x.com/2/tweets/${tweetId}`, {\n method: \"DELETE\",\n headers: { Authorization: `Bearer ${token}` },\n });\n\n if (resp.status === 429) {\n throw new Error(\"429 Rate limited\");\n }\n\n if (resp.status !== 200) {\n const text = await resp.text();\n throw new Error(`Delete tweet failed: HTTP ${resp.status} \u2014 ${text}`);\n }\n\n const json = (await resp.json()) as { data: { deleted: boolean } };\n return {\n data: json.data,\n rateLimit: parseRateLimitHeaders(resp.headers),\n };\n });\n}\n\nexport async function repost(\n http: HttpClient,\n token: string,\n userId: string,\n tweetId: string,\n): Promise<{ data: { retweeted: boolean }; rateLimit: RateLimitHeaders }> {\n return withRetry(async () => {\n const resp = await http.fetch(`https://api.x.com/2/users/${userId}/retweets`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({ tweet_id: tweetId }),\n });\n\n if (resp.status === 429) {\n throw new Error(\"429 Rate limited\");\n }\n\n if (resp.status !== 200) {\n const text = await resp.text();\n throw new Error(`Repost failed: HTTP ${resp.status} \u2014 ${text}`);\n }\n\n const json = (await resp.json()) as { data: { retweeted: boolean } };\n return {\n data: json.data,\n rateLimit: parseRateLimitHeaders(resp.headers),\n };\n });\n}\n\nexport async function undoRepost(\n http: HttpClient,\n token: string,\n userId: string,\n tweetId: string,\n): Promise<{ data: { retweeted: boolean }; rateLimit: RateLimitHeaders }> {\n return withRetry(async () => {\n const resp = await http.fetch(`https://api.x.com/2/users/${userId}/retweets/${tweetId}`, {\n method: \"DELETE\",\n headers: { Authorization: `Bearer ${token}` },\n });\n\n if (resp.status === 429) {\n throw new Error(\"429 Rate limited\");\n }\n\n if (resp.status !== 200) {\n const text = await resp.text();\n throw new Error(`Undo repost failed: HTTP ${resp.status} \u2014 ${text}`);\n }\n\n const json = (await resp.json()) as { data: { retweeted: boolean } };\n return {\n data: json.data,\n rateLimit: parseRateLimitHeaders(resp.headers),\n };\n });\n}\n", "import type { PluginContext } from \"@paperclipai/plugin-sdk\";\nimport { STATE_KEYS, accountStateKey } from \"../constants.js\";\nimport type { RateLimitHeaders, RateLimitState } from \"../types.js\";\n\nfunction stateKey(key: string) {\n return { scopeKind: \"instance\" as const, stateKey: key };\n}\n\nconst DEFAULT_STATE: RateLimitState = {\n post_tweets: { remaining: 99, reset_at: 0 },\n delete_tweets: { remaining: 99, reset_at: 0 },\n retweets: { remaining: 99, reset_at: 0 },\n daily_posts: 0,\n daily_reset_at: 0,\n};\n\nasync function getRateLimitState(ctx: PluginContext, handle: string): Promise<RateLimitState> {\n const raw = await ctx.state.get(stateKey(accountStateKey(STATE_KEYS.rateLimits, handle)));\n if (!raw) return { ...DEFAULT_STATE };\n const state = raw as unknown as RateLimitState;\n\n if (state.daily_reset_at && Date.now() > state.daily_reset_at) {\n state.daily_posts = 0;\n state.daily_reset_at = getNextMidnightMs();\n }\n\n return state;\n}\n\nfunction getNextMidnightMs(): number {\n const now = new Date();\n const tomorrow = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1);\n return tomorrow.getTime();\n}\n\nexport async function updateRateLimits(\n ctx: PluginContext,\n handle: string,\n endpoint: \"post_tweets\" | \"delete_tweets\" | \"retweets\",\n headers: RateLimitHeaders,\n): Promise<void> {\n const state = await getRateLimitState(ctx, handle);\n\n state[endpoint] = {\n remaining: headers.remaining,\n reset_at: headers.reset_at,\n };\n\n if (endpoint === \"post_tweets\") {\n state.daily_posts++;\n if (!state.daily_reset_at) {\n state.daily_reset_at = getNextMidnightMs();\n }\n }\n\n await ctx.state.set(\n stateKey(accountStateKey(STATE_KEYS.rateLimits, handle)),\n state as unknown as Record<string, unknown>,\n );\n}\n\nexport async function checkRateLimit(\n ctx: PluginContext,\n handle: string,\n endpoint: \"post_tweets\" | \"delete_tweets\" | \"retweets\",\n dailyLimit?: number,\n): Promise<{ ok: boolean; reason?: string }> {\n const state = await getRateLimitState(ctx, handle);\n const limit = state[endpoint];\n\n if (limit.remaining <= 0 && limit.reset_at > Date.now()) {\n const resetIn = Math.ceil((limit.reset_at - Date.now()) / 60000);\n return { ok: false, reason: `Rate limit exhausted for ${endpoint} on @${handle}. Resets in ${resetIn}m.` };\n }\n\n if (dailyLimit && endpoint === \"post_tweets\" && state.daily_posts >= dailyLimit) {\n return { ok: false, reason: `Daily post limit (${dailyLimit}) reached for @${handle}.` };\n }\n\n return { ok: true };\n}\n", "import type { PluginContext } from \"@paperclipai/plugin-sdk\";\nimport type { ApprovalModes, PublishingConfig, DraftData } from \"../types.js\";\nimport { ENTITY_TYPES, EVENT_NAMES, DEFAULT_APPROVAL_MODES } from \"../constants.js\";\n\ntype ContentType = \"posts\" | \"replies\" | \"quotes\" | \"reposts\" | \"scheduled\";\n\ninterface ApprovalResult {\n allowed: boolean;\n reason?: string;\n}\n\nexport async function checkApproval(\n ctx: PluginContext,\n config: PublishingConfig,\n contentType: ContentType,\n draftId?: string,\n approvalModes?: ApprovalModes,\n): Promise<ApprovalResult> {\n const modes = approvalModes || DEFAULT_APPROVAL_MODES;\n const mode = modes[contentType];\n\n if (mode === \"none\") {\n return { allowed: true };\n }\n\n if (mode === \"optional\") {\n ctx.logger.info(`Approval optional for ${contentType}, proceeding`);\n return { allowed: true };\n }\n\n // mode === \"required\"\n if (!draftId) {\n const issue = await ctx.issues.create({\n companyId: config.company_id,\n title: `Approval required for ${contentType}`,\n description: `Content type \"${contentType}\" requires approval but no draft was provided for review.\\n\\nCreate a draft first, then have it approved before publishing.`,\n });\n await ctx.issues.update(issue.id, { status: \"todo\" as const }, config.company_id);\n\n await ctx.events.emit(EVENT_NAMES.approvalRequired, config.company_id, {\n content_type: contentType,\n reason: \"No draft provided for required approval\",\n });\n\n return { allowed: false, reason: `Approval required for ${contentType}. Create a draft and get it approved first.` };\n }\n\n // Find draft by ID\n const allDrafts = await ctx.entities.list({ entityType: ENTITY_TYPES.draft, limit: 500 });\n const entity = allDrafts.find((e) => e.id === draftId);\n if (!entity) {\n return { allowed: false, reason: `Draft ${draftId} not found.` };\n }\n\n const draft = entity.data as unknown as DraftData;\n if (draft.status === \"approved\") {\n return { allowed: true };\n }\n\n // Draft exists but not approved \u2014 move to in_review\n if (draft.status !== \"in_review\") {\n draft.status = \"in_review\";\n const issue = await ctx.issues.create({\n companyId: config.company_id,\n title: `Review draft: ${draft.text.slice(0, 60)}`,\n description: `Draft ID: ${draftId}\\nFormat: ${draft.format}\\n\\nText:\\n${draft.text}${draft.thread_tweets ? \"\\n\\nThread:\\n\" + draft.thread_tweets.join(\"\\n---\\n\") : \"\"}`,\n });\n await ctx.issues.update(issue.id, { status: \"todo\" as const }, config.company_id);\n\n draft.review_issue_id = issue.id;\n await ctx.entities.upsert({\n entityType: ENTITY_TYPES.draft,\n scopeKind: \"instance\",\n externalId: entity.externalId ?? undefined,\n title: entity.title ?? draft.text.slice(0, 60),\n data: draft as unknown as Record<string, unknown>,\n });\n\n await ctx.events.emit(EVENT_NAMES.approvalRequired, config.company_id, {\n draft_id: draftId,\n content_type: contentType,\n reason: \"Draft submitted for review\",\n });\n }\n\n return { allowed: false, reason: `Draft ${draftId} is ${draft.status}. Approval required before publishing.` };\n}\n", "import type { PluginContext } from \"@paperclipai/plugin-sdk\";\nimport { ENTITY_TYPES } from \"../constants.js\";\nimport type { ContentMetadata, PublishedPostData } from \"../types.js\";\nimport { createTweet } from \"./x-api-write-client.js\";\nimport { updateRateLimits } from \"./rate-limiter.js\";\n\nconst MAX_RETRIES = 3;\n\nexport interface ThreadResult {\n tweetIds: string[];\n partial: boolean;\n}\n\nexport async function publishThread(\n ctx: PluginContext,\n token: string,\n handle: string,\n tweets: string[],\n metadata: ContentMetadata,\n companyId: string,\n): Promise<ThreadResult> {\n const tweetIds: string[] = [];\n let replyTo: string | undefined;\n\n for (let i = 0; i < tweets.length; i++) {\n const text = tweets[i]!;\n let posted = false;\n\n for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {\n try {\n const result = await createTweet(ctx.http, token, {\n text,\n reply_to: replyTo,\n });\n await updateRateLimits(ctx, handle, \"post_tweets\", result.rateLimit);\n\n tweetIds.push(result.data.id);\n replyTo = result.data.id;\n\n const published: PublishedPostData = {\n tweet_id: result.data.id,\n text: result.data.text,\n published_at: new Date().toISOString(),\n format: \"thread\",\n thread_tweet_ids: tweetIds.slice(),\n metadata,\n };\n\n await ctx.entities.upsert({\n entityType: ENTITY_TYPES.publishedPost,\n scopeKind: \"instance\",\n externalId: result.data.id,\n title: `Thread ${i + 1}/${tweets.length}: ${text.slice(0, 40)}`,\n data: published as unknown as Record<string, unknown>,\n });\n\n posted = true;\n break;\n } catch (err) {\n ctx.logger.error(`Thread tweet ${i + 1}/${tweets.length} attempt ${attempt + 1} failed`, { error: String(err) });\n if (attempt < MAX_RETRIES - 1) {\n await new Promise((r) => setTimeout(r, Math.pow(2, attempt + 1) * 1000));\n }\n }\n }\n\n if (!posted) {\n const issue = await ctx.issues.create({\n companyId,\n title: `Thread publish failed at tweet ${i + 1}/${tweets.length}`,\n description: `Thread was partially published.\\n\\nPublished tweet IDs: ${tweetIds.join(\", \")}\\n\\nFailed tweet text: ${text}\\n\\nRemaining tweets: ${tweets.length - i}`,\n });\n await ctx.issues.update(issue.id, { status: \"todo\" as const }, companyId);\n\n return { tweetIds, partial: true };\n }\n }\n\n return { tweetIds, partial: false };\n}\n", "import {\n definePlugin,\n runWorker,\n type PluginContext,\n type PluginJobContext,\n type ToolResult,\n} from \"@paperclipai/plugin-sdk\";\nimport {\n DEFAULT_CONFIG,\n accountStateKey,\n ENTITY_TYPES,\n EVENT_NAMES,\n JOB_KEYS,\n STATE_KEYS,\n TOOL_NAMES,\n} from \"./constants.js\";\nimport type {\n AccountConfig,\n PublishingConfig,\n TokenState,\n DraftData,\n PublishedPostData,\n RateLimitState,\n} from \"./types.js\";\nimport { getValidAccessToken, getTokens, setTokens, refreshTokens } from \"./pipeline/oauth-manager.js\";\nimport { createTweet } from \"./pipeline/x-api-write-client.js\";\nimport { repost as apiRepost } from \"./pipeline/x-api-write-client.js\";\nimport { updateRateLimits } from \"./pipeline/rate-limiter.js\";\nimport { checkApproval } from \"./pipeline/approval-gate.js\";\nimport { publishThread } from \"./pipeline/thread-publisher.js\";\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction stateKey(key: string) {\n return { scopeKind: \"instance\" as const, stateKey: key };\n}\n\nasync function getConfig(ctx: PluginContext): Promise<PublishingConfig> {\n const raw = await ctx.config.get();\n return { ...DEFAULT_CONFIG, ...raw } as unknown as PublishingConfig;\n}\n\n/** Resolve which account to use. Returns the AccountConfig or an error string. */\nfunction resolveAccount(\n config: PublishingConfig,\n handle?: string,\n): { ok: true; handle: string; account: AccountConfig } | { ok: false; error: string } {\n const accounts = config.accounts || {};\n const handles = Object.keys(accounts);\n\n if (handles.length === 0) {\n return { ok: false, error: \"No accounts configured.\" };\n }\n\n const target = handle || config.default_account || handles[0]!;\n const account = accounts[target];\n if (!account) {\n return { ok: false, error: `Account @${target} not found in config. Available: ${handles.join(\", \")}` };\n }\n\n return { ok: true, handle: target, account };\n}\n\ninterface EntityRecord {\n id: string;\n entityType: string;\n externalId: string | null;\n title: string | null;\n status: string | null;\n data: Record<string, unknown>;\n createdAt: string;\n updatedAt: string;\n}\n\nfunction findEntityById<T>(entities: EntityRecord[], id: string): { id: string; data: T; raw: EntityRecord } | null {\n const found = entities.find((e) => e.id === id);\n if (!found) return null;\n return { id: found.id, data: found.data as unknown as T, raw: found };\n}\n\n// ---------------------------------------------------------------------------\n// Tool handlers\n// ---------------------------------------------------------------------------\n\nasync function handleSetupOauth(ctx: PluginContext, params: Record<string, unknown>): Promise<ToolResult> {\n const handle = params.account as string;\n if (!handle) return { error: \"account param is required (X handle to store tokens for).\" };\n\n const config = await getConfig(ctx);\n const resolved = resolveAccount(config, handle);\n if (!resolved.ok) return { error: resolved.error };\n\n const accessToken = params.access_token as string;\n const refreshToken = params.refresh_token as string;\n const expiresIn = (params.expires_in as number) || 7200;\n\n const tokenState: TokenState = {\n access_token: accessToken,\n refresh_token: refreshToken,\n expires_at: Date.now() + expiresIn * 1000,\n };\n await setTokens(ctx, handle, tokenState);\n\n return { content: `OAuth tokens stored for @${handle}. Expires at ${new Date(tokenState.expires_at).toISOString()}.` };\n}\n\nasync function handleDraftPost(ctx: PluginContext, params: Record<string, unknown>): Promise<ToolResult> {\n const text = params.text as string;\n if (text.length > 280) {\n return { error: `Tweet text exceeds 280 characters (${text.length}).` };\n }\n\n const config = await getConfig(ctx);\n const format = (params.format as string) || \"single\";\n const metadata = (params.metadata as DraftData[\"metadata\"]) || {};\n\n const draft: DraftData = {\n text,\n format: format as DraftData[\"format\"],\n reply_to_tweet_id: params.reply_to_tweet_id as string | undefined,\n quote_tweet_id: params.quote_tweet_id as string | undefined,\n schedule_at: params.schedule_at as string | undefined,\n status: \"draft\",\n metadata,\n };\n\n const entity = await ctx.entities.upsert({\n entityType: ENTITY_TYPES.draft,\n scopeKind: \"instance\",\n title: text.slice(0, 60),\n data: draft as unknown as Record<string, unknown>,\n });\n\n await ctx.events.emit(EVENT_NAMES.draftCreated, config.company_id, {\n draft_id: entity.id,\n format,\n metadata,\n });\n\n return { content: JSON.stringify({ draft_id: entity.id, status: \"draft\", format }) };\n}\n\nasync function handleDraftThread(ctx: PluginContext, params: Record<string, unknown>): Promise<ToolResult> {\n const threadTweets = params.thread_tweets as string[];\n if (!threadTweets || threadTweets.length < 2) {\n return { error: \"Thread must have at least 2 tweets.\" };\n }\n\n for (let i = 0; i < threadTweets.length; i++) {\n if (threadTweets[i]!.length > 280) {\n return { error: `Tweet ${i + 1} exceeds 280 characters (${threadTweets[i]!.length}).` };\n }\n }\n\n const config = await getConfig(ctx);\n const metadata = (params.metadata as DraftData[\"metadata\"]) || {};\n const draft: DraftData = {\n text: threadTweets[0]!,\n format: \"thread\",\n thread_tweets: threadTweets,\n schedule_at: params.schedule_at as string | undefined,\n status: \"draft\",\n metadata,\n };\n\n const entity = await ctx.entities.upsert({\n entityType: ENTITY_TYPES.draft,\n scopeKind: \"instance\",\n title: `Thread: ${threadTweets[0]!.slice(0, 50)}`,\n data: draft as unknown as Record<string, unknown>,\n });\n\n await ctx.events.emit(EVENT_NAMES.draftCreated, config.company_id, {\n draft_id: entity.id,\n format: \"thread\",\n metadata,\n });\n\n return { content: JSON.stringify({ draft_id: entity.id, status: \"draft\", format: \"thread\", tweet_count: threadTweets.length }) };\n}\n\nasync function handleUpdateDraft(ctx: PluginContext, params: Record<string, unknown>): Promise<ToolResult> {\n const draftId = params.draft_id as string;\n const entities = await ctx.entities.list({ entityType: ENTITY_TYPES.draft, limit: 500 });\n const match = findEntityById<DraftData>(entities, draftId);\n if (!match) return { error: `Draft ${draftId} not found.` };\n\n const data = match.data;\n if (params.text !== undefined) data.text = params.text as string;\n if (params.thread_tweets !== undefined) data.thread_tweets = params.thread_tweets as string[];\n if (params.schedule_at !== undefined) data.schedule_at = params.schedule_at as string;\n if (params.metadata !== undefined) data.metadata = { ...data.metadata, ...(params.metadata as DraftData[\"metadata\"]) };\n data.status = \"draft\"; // reset to draft on edit\n\n await ctx.entities.upsert({\n entityType: ENTITY_TYPES.draft,\n scopeKind: \"instance\",\n externalId: match.raw.externalId ?? undefined,\n title: data.text.slice(0, 60),\n data: data as unknown as Record<string, unknown>,\n });\n\n return { content: JSON.stringify({ draft_id: draftId, status: \"draft\", updated: true }) };\n}\n\nasync function handlePublishPost(ctx: PluginContext, params: Record<string, unknown>): Promise<ToolResult> {\n const config = await getConfig(ctx);\n const resolved = resolveAccount(config, params.account as string | undefined);\n if (!resolved.ok) return { error: resolved.error };\n const { handle, account } = resolved;\n\n let text = params.text as string | undefined;\n let metadata = (params.metadata as PublishedPostData[\"metadata\"]) || {};\n const draftId = params.draft_id as string | undefined;\n\n if (draftId) {\n const entities = await ctx.entities.list({ entityType: ENTITY_TYPES.draft, limit: 500 });\n const match = findEntityById<DraftData>(entities, draftId);\n if (!match) return { error: `Draft ${draftId} not found.` };\n text = match.data.text;\n metadata = { ...match.data.metadata, ...metadata };\n }\n\n if (!text) return { error: \"No text provided and no draft_id.\" };\n\n const approval = await checkApproval(ctx, config, \"posts\", draftId, account.approval_modes);\n if (!approval.allowed) return { error: `Blocked: ${approval.reason}` };\n\n const token = await getValidAccessToken(ctx, config, handle);\n const result = await createTweet(ctx.http, token, { text });\n await updateRateLimits(ctx, handle, \"post_tweets\", result.rateLimit);\n\n const published: PublishedPostData = {\n tweet_id: result.data.id,\n text: result.data.text,\n published_at: new Date().toISOString(),\n draft_id: draftId,\n format: \"single\",\n metadata,\n };\n\n await ctx.entities.upsert({\n entityType: ENTITY_TYPES.publishedPost,\n scopeKind: \"instance\",\n externalId: result.data.id,\n title: text.slice(0, 60),\n data: published as unknown as Record<string, unknown>,\n });\n\n await ctx.events.emit(EVENT_NAMES.postPublished, config.company_id, {\n tweet_id: result.data.id, text, format: \"single\", metadata,\n });\n\n return { content: JSON.stringify({ tweet_id: result.data.id, text: result.data.text, status: \"published\" }) };\n}\n\nasync function handleReplyToTweet(ctx: PluginContext, params: Record<string, unknown>): Promise<ToolResult> {\n const config = await getConfig(ctx);\n const resolved = resolveAccount(config, params.account as string | undefined);\n if (!resolved.ok) return { error: resolved.error };\n const { handle, account } = resolved;\n\n const tweetId = params.tweet_id as string;\n const text = params.text as string;\n const metadata = (params.metadata as PublishedPostData[\"metadata\"]) || {};\n\n const approval = await checkApproval(ctx, config, \"replies\", params.draft_id as string | undefined, account.approval_modes);\n if (!approval.allowed) return { error: `Blocked: ${approval.reason}` };\n\n const token = await getValidAccessToken(ctx, config, handle);\n const result = await createTweet(ctx.http, token, { text, reply_to: tweetId });\n await updateRateLimits(ctx, handle, \"post_tweets\", result.rateLimit);\n\n const published: PublishedPostData = {\n tweet_id: result.data.id,\n text: result.data.text,\n published_at: new Date().toISOString(),\n draft_id: params.draft_id as string | undefined,\n format: \"reply\",\n metadata: { ...metadata, source_tweet_id: tweetId },\n };\n\n await ctx.entities.upsert({\n entityType: ENTITY_TYPES.publishedPost,\n scopeKind: \"instance\",\n externalId: result.data.id,\n title: `Reply: ${text.slice(0, 50)}`,\n data: published as unknown as Record<string, unknown>,\n });\n\n await ctx.events.emit(EVENT_NAMES.postPublished, config.company_id, {\n tweet_id: result.data.id, text, format: \"reply\", metadata: published.metadata,\n });\n\n return { content: JSON.stringify({ tweet_id: result.data.id, text: result.data.text, status: \"published\", reply_to: tweetId }) };\n}\n\nasync function handleQuoteTweet(ctx: PluginContext, params: Record<string, unknown>): Promise<ToolResult> {\n const config = await getConfig(ctx);\n const resolved = resolveAccount(config, params.account as string | undefined);\n if (!resolved.ok) return { error: resolved.error };\n const { handle, account } = resolved;\n\n const tweetId = params.tweet_id as string;\n const text = params.text as string;\n const metadata = (params.metadata as PublishedPostData[\"metadata\"]) || {};\n\n const approval = await checkApproval(ctx, config, \"quotes\", params.draft_id as string | undefined, account.approval_modes);\n if (!approval.allowed) return { error: `Blocked: ${approval.reason}` };\n\n const token = await getValidAccessToken(ctx, config, handle);\n const result = await createTweet(ctx.http, token, { text, quote_tweet_id: tweetId });\n await updateRateLimits(ctx, handle, \"post_tweets\", result.rateLimit);\n\n const published: PublishedPostData = {\n tweet_id: result.data.id,\n text: result.data.text,\n published_at: new Date().toISOString(),\n draft_id: params.draft_id as string | undefined,\n format: \"quote\",\n metadata: { ...metadata, source_tweet_id: tweetId },\n };\n\n await ctx.entities.upsert({\n entityType: ENTITY_TYPES.publishedPost,\n scopeKind: \"instance\",\n externalId: result.data.id,\n title: `Quote: ${text.slice(0, 50)}`,\n data: published as unknown as Record<string, unknown>,\n });\n\n await ctx.events.emit(EVENT_NAMES.postPublished, config.company_id, {\n tweet_id: result.data.id, text, format: \"quote\", metadata: published.metadata,\n });\n\n return { content: JSON.stringify({ tweet_id: result.data.id, text: result.data.text, status: \"published\", quoted: tweetId }) };\n}\n\nasync function handleRepost(ctx: PluginContext, params: Record<string, unknown>): Promise<ToolResult> {\n const config = await getConfig(ctx);\n const resolved = resolveAccount(config, params.account as string | undefined);\n if (!resolved.ok) return { error: resolved.error };\n const { handle, account } = resolved;\n\n const tweetId = params.tweet_id as string;\n\n const approval = await checkApproval(ctx, config, \"reposts\", params.draft_id as string | undefined, account.approval_modes);\n if (!approval.allowed) return { error: `Blocked: ${approval.reason}` };\n\n const token = await getValidAccessToken(ctx, config, handle);\n const result = await apiRepost(ctx.http, token, account.x_user_id, tweetId);\n await updateRateLimits(ctx, handle, \"retweets\", result.rateLimit);\n\n const published: PublishedPostData = {\n tweet_id: tweetId,\n text: \"\",\n published_at: new Date().toISOString(),\n draft_id: params.draft_id as string | undefined,\n format: \"repost\",\n metadata: { source_tweet_id: tweetId },\n };\n\n await ctx.entities.upsert({\n entityType: ENTITY_TYPES.publishedPost,\n scopeKind: \"instance\",\n externalId: `repost-${tweetId}`,\n title: `Repost: ${tweetId}`,\n data: published as unknown as Record<string, unknown>,\n });\n\n await ctx.events.emit(EVENT_NAMES.postPublished, config.company_id, {\n tweet_id: tweetId, text: \"\", format: \"repost\", metadata: published.metadata,\n });\n\n return { content: JSON.stringify({ tweet_id: tweetId, status: \"reposted\" }) };\n}\n\nasync function handleSchedulePost(ctx: PluginContext, params: Record<string, unknown>): Promise<ToolResult> {\n const scheduleAt = params.schedule_at as string;\n const draftId = params.draft_id as string | undefined;\n const text = params.text as string | undefined;\n const metadata = (params.metadata as DraftData[\"metadata\"]) || {};\n\n if (draftId) {\n const entities = await ctx.entities.list({ entityType: ENTITY_TYPES.draft, limit: 500 });\n const match = findEntityById<DraftData>(entities, draftId);\n if (!match) return { error: `Draft ${draftId} not found.` };\n match.data.schedule_at = scheduleAt;\n await ctx.entities.upsert({\n entityType: ENTITY_TYPES.draft,\n scopeKind: \"instance\",\n externalId: match.raw.externalId ?? undefined,\n title: match.data.text.slice(0, 60),\n data: match.data as unknown as Record<string, unknown>,\n });\n return { content: JSON.stringify({ draft_id: draftId, schedule_at: scheduleAt, status: \"scheduled\" }) };\n }\n\n if (!text) return { error: \"Provide text or draft_id.\" };\n\n const draft: DraftData = {\n text,\n format: \"single\",\n schedule_at: scheduleAt,\n status: \"draft\",\n metadata,\n };\n\n const entity = await ctx.entities.upsert({\n entityType: ENTITY_TYPES.draft,\n scopeKind: \"instance\",\n title: text.slice(0, 60),\n data: draft as unknown as Record<string, unknown>,\n });\n\n return { content: JSON.stringify({ draft_id: entity.id, schedule_at: scheduleAt, status: \"scheduled\" }) };\n}\n\nasync function handlePublishThread(ctx: PluginContext, params: Record<string, unknown>): Promise<ToolResult> {\n const config = await getConfig(ctx);\n const resolved = resolveAccount(config, params.account as string | undefined);\n if (!resolved.ok) return { error: resolved.error };\n const { handle, account } = resolved;\n\n let threadTweets = params.thread_tweets as string[] | undefined;\n let metadata = (params.metadata as PublishedPostData[\"metadata\"]) || {};\n const draftId = params.draft_id as string | undefined;\n\n if (draftId) {\n const entities = await ctx.entities.list({ entityType: ENTITY_TYPES.draft, limit: 500 });\n const match = findEntityById<DraftData>(entities, draftId);\n if (!match) return { error: `Draft ${draftId} not found.` };\n threadTweets = match.data.thread_tweets;\n metadata = { ...match.data.metadata, ...metadata };\n }\n\n if (!threadTweets || threadTweets.length < 2) {\n return { error: \"Thread must have at least 2 tweets.\" };\n }\n\n const approval = await checkApproval(ctx, config, \"posts\", draftId, account.approval_modes);\n if (!approval.allowed) return { error: `Blocked: ${approval.reason}` };\n\n const token = await getValidAccessToken(ctx, config, handle);\n const result = await publishThread(ctx, token, handle, threadTweets, metadata, config.company_id);\n\n await ctx.events.emit(EVENT_NAMES.threadPublished, config.company_id, {\n tweet_ids: result.tweetIds,\n thread_length: threadTweets.length,\n partial: result.partial,\n });\n\n for (const tweetId of result.tweetIds) {\n await ctx.events.emit(EVENT_NAMES.postPublished, config.company_id, {\n tweet_id: tweetId, text: \"\", format: \"thread\", metadata,\n });\n }\n\n return { content: JSON.stringify({\n tweet_ids: result.tweetIds,\n thread_length: threadTweets.length,\n partial: result.partial,\n status: result.partial ? \"partial\" : \"published\",\n }) };\n}\n\nasync function handleGetDrafts(ctx: PluginContext, params: Record<string, unknown>): Promise<ToolResult> {\n const statusFilter = params.status as string | undefined;\n const limit = (params.limit as number) || 20;\n\n const entities = await ctx.entities.list({ entityType: ENTITY_TYPES.draft, limit: 100 });\n let drafts = entities.map((e) => ({ id: e.id, ...(e.data as unknown as DraftData) }));\n\n if (statusFilter) {\n drafts = drafts.filter((d) => d.status === statusFilter);\n }\n\n return { content: JSON.stringify(drafts.slice(0, limit)) };\n}\n\nasync function handleGetSchedule(ctx: PluginContext, params: Record<string, unknown>): Promise<ToolResult> {\n const limit = (params.limit as number) || 20;\n const entities = await ctx.entities.list({ entityType: ENTITY_TYPES.draft, limit: 100 });\n const scheduled = entities\n .map((e) => ({ id: e.id, ...(e.data as unknown as DraftData) }))\n .filter((d) => d.schedule_at && (d.status === \"draft\" || d.status === \"approved\"))\n .sort((a, b) => (a.schedule_at! > b.schedule_at! ? 1 : -1));\n\n return { content: JSON.stringify(scheduled.slice(0, limit)) };\n}\n\nasync function handleGetPostMetrics(ctx: PluginContext, params: Record<string, unknown>): Promise<ToolResult> {\n const tweetId = params.tweet_id as string;\n const entities = await ctx.entities.list({ entityType: ENTITY_TYPES.publishedPost, limit: 500 });\n const post = entities.find((e) => (e.data as unknown as PublishedPostData).tweet_id === tweetId);\n\n if (!post) return { error: `No published post found for tweet ${tweetId}.` };\n\n const data = post.data as unknown as PublishedPostData;\n return { content: JSON.stringify({\n tweet_id: data.tweet_id,\n text: data.text,\n published_at: data.published_at,\n format: data.format,\n metadata: data.metadata,\n metrics: data.metrics || null,\n }) };\n}\n\nasync function handleGetAccountStatus(ctx: PluginContext, params: Record<string, unknown>): Promise<ToolResult> {\n const config = await getConfig(ctx);\n const accounts = config.accounts || {};\n const handles = params.account ? [params.account as string] : Object.keys(accounts);\n\n const today = new Date().toISOString().split(\"T\")[0]!;\n const entities = await ctx.entities.list({ entityType: ENTITY_TYPES.publishedPost, limit: 500 });\n\n const statuses = [];\n for (const handle of handles) {\n let tokenHealth = \"unknown\";\n try {\n const tokens = await getTokens(ctx, handle);\n if (tokens.expires_at > Date.now()) {\n const minutesLeft = Math.round((tokens.expires_at - Date.now()) / 60000);\n tokenHealth = `valid (${minutesLeft}m remaining)`;\n } else {\n tokenHealth = \"expired\";\n }\n } catch {\n tokenHealth = \"no tokens stored\";\n }\n\n let rateLimits: RateLimitState | null = null;\n try {\n const raw = await ctx.state.get(stateKey(accountStateKey(STATE_KEYS.rateLimits, handle)));\n if (raw) rateLimits = raw as unknown as RateLimitState;\n } catch { /* no rate limit data yet */ }\n\n const todayCount = entities.filter((e) => {\n const data = e.data as unknown as PublishedPostData;\n return data.published_at.startsWith(today);\n }).length;\n\n statuses.push({\n x_handle: handle,\n role: accounts[handle]?.role || \"unknown\",\n token_health: tokenHealth,\n daily_posts: { count: todayCount, limit: config.daily_post_limit },\n rate_limits: rateLimits,\n });\n }\n\n return { content: JSON.stringify(handles.length === 1 ? statuses[0] : statuses) };\n}\n\n// ---------------------------------------------------------------------------\n// Job handlers\n// ---------------------------------------------------------------------------\n\nasync function handleTokenRefresh(ctx: PluginContext, _job: PluginJobContext): Promise<void> {\n const config = await getConfig(ctx);\n const handles = Object.keys(config.accounts || {});\n\n for (const handle of handles) {\n try {\n await refreshTokens(ctx, config, handle);\n ctx.logger.info(`Token refresh succeeded for @${handle}`);\n } catch (err) {\n ctx.logger.error(`Token refresh failed for @${handle}`, { error: String(err) });\n const issue = await ctx.issues.create({\n companyId: config.company_id,\n title: `OAuth token refresh failed for @${handle}`,\n description: `Token refresh failed for @${handle} at ${new Date().toISOString()}.\\n\\nError: ${String(err)}\\n\\nManual re-auth may be required via setup-oauth tool.`,\n });\n await ctx.issues.update(issue.id, { status: \"todo\" as const }, config.company_id);\n }\n }\n}\n\nasync function handlePublishScheduled(ctx: PluginContext, _job: PluginJobContext): Promise<void> {\n const config = await getConfig(ctx);\n const resolved = resolveAccount(config);\n if (!resolved.ok) { ctx.logger.error(resolved.error); return; }\n const { handle } = resolved;\n\n const now = new Date().toISOString();\n const entities = await ctx.entities.list({ entityType: ENTITY_TYPES.draft, limit: 100 });\n const due = entities.filter((e) => {\n const d = e.data as unknown as DraftData;\n return d.schedule_at && d.schedule_at <= now && (d.status === \"approved\" || d.status === \"draft\");\n });\n\n for (const entity of due) {\n const draft = entity.data as unknown as DraftData;\n const approval = await checkApproval(ctx, config, \"scheduled\", entity.id, resolved.account.approval_modes);\n if (!approval.allowed) {\n ctx.logger.info(`Scheduled draft ${entity.id} blocked: ${approval.reason}`);\n continue;\n }\n\n try {\n const token = await getValidAccessToken(ctx, config, handle);\n\n if (draft.format === \"thread\" && draft.thread_tweets) {\n await publishThread(ctx, token, draft.thread_tweets, draft.metadata, config.company_id);\n } else {\n const result = await createTweet(ctx.http, token, {\n text: draft.text,\n reply_to: draft.reply_to_tweet_id,\n quote_tweet_id: draft.quote_tweet_id,\n });\n await updateRateLimits(ctx, handle, \"post_tweets\", result.rateLimit);\n\n await ctx.entities.upsert({\n entityType: ENTITY_TYPES.publishedPost,\n scopeKind: \"instance\",\n externalId: result.data.id,\n title: draft.text.slice(0, 60),\n data: {\n tweet_id: result.data.id,\n text: result.data.text,\n published_at: new Date().toISOString(),\n draft_id: entity.id,\n format: draft.format,\n metadata: draft.metadata,\n } as unknown as Record<string, unknown>,\n });\n\n await ctx.events.emit(EVENT_NAMES.postPublished, config.company_id, {\n tweet_id: result.data.id,\n text: draft.text,\n format: draft.format,\n metadata: draft.metadata,\n });\n }\n\n // Mark draft as published\n draft.status = \"approved\";\n await ctx.entities.upsert({\n entityType: ENTITY_TYPES.draft,\n scopeKind: \"instance\",\n externalId: entity.externalId ?? undefined,\n title: entity.title ?? draft.text.slice(0, 60),\n data: draft as unknown as Record<string, unknown>,\n });\n\n ctx.logger.info(`Published scheduled draft ${entity.id}`);\n } catch (err) {\n ctx.logger.error(`Failed to publish scheduled draft ${entity.id}`, { error: String(err) });\n }\n }\n}\n\nasync function handleMetricsCapture(ctx: PluginContext, _job: PluginJobContext): Promise<void> {\n const config = await getConfig(ctx);\n const resolved = resolveAccount(config);\n if (!resolved.ok) { ctx.logger.error(resolved.error); return; }\n const { handle } = resolved;\n\n const lookbackMs = config.metrics_capture_lookback_days * 86400000;\n const cutoff = new Date(Date.now() - lookbackMs).toISOString();\n const entities = await ctx.entities.list({ entityType: ENTITY_TYPES.publishedPost, limit: 500 });\n const recent = entities.filter((e) => {\n const d = e.data as unknown as PublishedPostData;\n return d.published_at >= cutoff && d.format !== \"repost\";\n });\n\n if (recent.length === 0) return;\n\n const tweetIds = recent.map((e) => (e.data as unknown as PublishedPostData).tweet_id);\n const token = await getValidAccessToken(ctx, config, handle);\n\n const batchSize = 100;\n for (let i = 0; i < tweetIds.length; i += batchSize) {\n const batch = tweetIds.slice(i, i + batchSize);\n const url = `https://api.x.com/2/tweets?ids=${batch.join(\",\")}&tweet.fields=public_metrics`;\n const resp = await ctx.http.fetch(url, {\n headers: { Authorization: `Bearer ${token}` },\n });\n\n if (!resp.ok) {\n ctx.logger.error(\"Metrics capture batch failed\", { status: resp.status });\n continue;\n }\n\n const body = (await resp.json()) as { data?: Array<{ id: string; public_metrics: { like_count: number; retweet_count: number; reply_count: number; impression_count?: number } }> };\n if (!body.data) continue;\n\n for (const tweet of body.data) {\n const entity = recent.find((e) => (e.data as unknown as PublishedPostData).tweet_id === tweet.id);\n if (!entity) continue;\n\n const data = entity.data as unknown as PublishedPostData;\n const newMetrics = {\n likes: tweet.public_metrics.like_count,\n retweets: tweet.public_metrics.retweet_count,\n replies: tweet.public_metrics.reply_count,\n impressions: tweet.public_metrics.impression_count || 0,\n captured_at: new Date().toISOString(),\n };\n\n // Check milestones\n const totalEngagement = newMetrics.likes + newMetrics.retweets + newMetrics.replies;\n const prevTotal = data.metrics\n ? data.metrics.likes + data.metrics.retweets + data.metrics.replies\n : 0;\n\n for (const milestone of config.engagement_milestones) {\n if (totalEngagement >= milestone && prevTotal < milestone) {\n await ctx.events.emit(EVENT_NAMES.postEngagementMilestone, config.company_id, {\n tweet_id: tweet.id,\n milestone,\n current_metrics: newMetrics,\n });\n }\n }\n\n data.metrics = newMetrics;\n await ctx.entities.upsert({\n entityType: ENTITY_TYPES.publishedPost,\n scopeKind: \"instance\",\n externalId: entity.externalId ?? undefined,\n title: entity.title ?? data.text.slice(0, 60),\n data: data as unknown as Record<string, unknown>,\n });\n }\n }\n\n ctx.logger.info(`Metrics captured for ${recent.length} posts`);\n}\n\nasync function handleStaleDraftCleanup(ctx: PluginContext, _job: PluginJobContext): Promise<void> {\n const cutoff = new Date(Date.now() - 48 * 3600000).toISOString();\n const entities = await ctx.entities.list({ entityType: ENTITY_TYPES.draft, limit: 500 });\n let staleCount = 0;\n\n for (const entity of entities) {\n const data = entity.data as unknown as DraftData;\n if ((data.status === \"draft\" || data.status === \"in_review\") && entity.createdAt < cutoff) {\n data.status = \"stale\";\n await ctx.entities.upsert({\n entityType: ENTITY_TYPES.draft,\n scopeKind: \"instance\",\n externalId: entity.externalId ?? undefined,\n title: entity.title ?? data.text.slice(0, 60),\n data: data as unknown as Record<string, unknown>,\n });\n staleCount++;\n }\n }\n\n if (staleCount > 0) {\n ctx.logger.info(`Marked ${staleCount} drafts as stale`);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Plugin definition\n// ---------------------------------------------------------------------------\n\nlet pluginCtx: PluginContext | null = null;\n\nconst plugin = definePlugin({\n async setup(ctx) {\n pluginCtx = ctx;\n\n // Register job handlers\n ctx.jobs.register(JOB_KEYS.tokenRefresh, (job) => handleTokenRefresh(ctx, job));\n ctx.jobs.register(JOB_KEYS.publishScheduled, (job) => handlePublishScheduled(ctx, job));\n ctx.jobs.register(JOB_KEYS.metricsCapture, (job) => handleMetricsCapture(ctx, job));\n ctx.jobs.register(JOB_KEYS.staleDraftCleanup, (job) => handleStaleDraftCleanup(ctx, job));\n\n // Register agent tools\n const p = (params: unknown) => params as Record<string, unknown>;\n ctx.tools.register(\n TOOL_NAMES.setupOauth,\n { displayName: \"Setup OAuth\", description: \"Seed initial OAuth tokens\", parametersSchema: {} },\n (params) => handleSetupOauth(ctx, p(params)),\n );\n ctx.tools.register(\n TOOL_NAMES.draftPost,\n { displayName: \"Draft Post\", description: \"Create a draft post\", parametersSchema: {} },\n (params) => handleDraftPost(ctx, p(params)),\n );\n ctx.tools.register(\n TOOL_NAMES.draftThread,\n { displayName: \"Draft Thread\", description: \"Create a draft thread\", parametersSchema: {} },\n (params) => handleDraftThread(ctx, p(params)),\n );\n ctx.tools.register(\n TOOL_NAMES.updateDraft,\n { displayName: \"Update Draft\", description: \"Update an existing draft\", parametersSchema: {} },\n (params) => handleUpdateDraft(ctx, p(params)),\n );\n ctx.tools.register(\n TOOL_NAMES.publishPost,\n { displayName: \"Publish Post\", description: \"Publish a tweet to X\", parametersSchema: {} },\n (params) => handlePublishPost(ctx, p(params)),\n );\n ctx.tools.register(\n TOOL_NAMES.replyToTweet,\n { displayName: \"Reply to Tweet\", description: \"Post a reply to a tweet\", parametersSchema: {} },\n (params) => handleReplyToTweet(ctx, p(params)),\n );\n ctx.tools.register(\n TOOL_NAMES.quoteTweet,\n { displayName: \"Quote Tweet\", description: \"Post a quote tweet\", parametersSchema: {} },\n (params) => handleQuoteTweet(ctx, p(params)),\n );\n ctx.tools.register(\n TOOL_NAMES.repost,\n { displayName: \"Repost\", description: \"Repost a tweet\", parametersSchema: {} },\n (params) => handleRepost(ctx, p(params)),\n );\n ctx.tools.register(\n TOOL_NAMES.schedulePost,\n { displayName: \"Schedule Post\", description: \"Schedule a post for later\", parametersSchema: {} },\n (params) => handleSchedulePost(ctx, p(params)),\n );\n ctx.tools.register(\n TOOL_NAMES.publishThread,\n { displayName: \"Publish Thread\", description: \"Publish a multi-tweet thread\", parametersSchema: {} },\n (params) => handlePublishThread(ctx, p(params)),\n );\n ctx.tools.register(\n TOOL_NAMES.getDrafts,\n { displayName: \"Get Drafts\", description: \"Query drafts by status\", parametersSchema: {} },\n (params) => handleGetDrafts(ctx, p(params)),\n );\n ctx.tools.register(\n TOOL_NAMES.getSchedule,\n { displayName: \"Get Schedule\", description: \"Get upcoming scheduled posts\", parametersSchema: {} },\n (params) => handleGetSchedule(ctx, p(params)),\n );\n ctx.tools.register(\n TOOL_NAMES.getPostMetrics,\n { displayName: \"Get Post Metrics\", description: \"Get engagement metrics for a post\", parametersSchema: {} },\n (params) => handleGetPostMetrics(ctx, p(params)),\n );\n ctx.tools.register(\n TOOL_NAMES.getAccountStatus,\n { displayName: \"Get Account Status\", description: \"Account health and rate limits\", parametersSchema: {} },\n (params) => handleGetAccountStatus(ctx, p(params)),\n );\n\n // Register UI data handlers\n ctx.data.register(\"dashboard-summary\", async () => {\n const config = await getConfig(ctx);\n const accounts = config.accounts || {};\n const handles = Object.keys(accounts);\n const today = new Date().toISOString().split(\"T\")[0]!;\n const published = await ctx.entities.list({ entityType: ENTITY_TYPES.publishedPost, limit: 100 });\n const drafts = await ctx.entities.list({ entityType: ENTITY_TYPES.draft, limit: 100 });\n\n const todayPosts = published.filter((e) =>\n (e.data as unknown as PublishedPostData).published_at.startsWith(today),\n );\n\n const pendingDrafts = drafts.filter((e) => {\n const d = e.data as unknown as DraftData;\n return d.status === \"draft\" || d.status === \"in_review\" || d.status === \"approved\";\n });\n\n // Per-account token health summary\n const accountHealth: Record<string, string> = {};\n for (const handle of handles) {\n try {\n const tokens = await getTokens(ctx, handle);\n accountHealth[handle] = tokens.expires_at > Date.now() ? \"valid\" : \"expired\";\n } catch {\n accountHealth[handle] = \"not configured\";\n }\n }\n const allValid = Object.values(accountHealth).every((h) => h === \"valid\");\n const tokenHealth = handles.length === 0 ? \"no accounts\" : allValid ? \"valid\" : \"degraded\";\n\n const recentPosts = published\n .map((e) => e.data as unknown as PublishedPostData)\n .sort((a, b) => (a.published_at > b.published_at ? -1 : 1))\n .slice(0, 5);\n\n return {\n today_post_count: todayPosts.length,\n daily_limit: config.daily_post_limit,\n pending_drafts: pendingDrafts.length,\n token_health: tokenHealth,\n accounts: accountHealth,\n recent_posts: recentPosts,\n };\n });\n\n ctx.data.register(\"plugin-config\", async () => {\n const config = await getConfig(ctx);\n return config as unknown as Record<string, unknown>;\n });\n\n ctx.data.register(\"content-queue\", async () => {\n const allDrafts = await ctx.entities.list({ entityType: ENTITY_TYPES.draft, limit: 100 });\n\n const pending = allDrafts\n .map((e) => {\n const d = e.data as unknown as DraftData;\n return { id: e.id, text: d.text, format: d.format, status: d.status, schedule_at: d.schedule_at };\n })\n .filter((d) => (d.status === \"draft\" || d.status === \"in_review\" || d.status === \"approved\") && !d.schedule_at);\n\n const scheduled = allDrafts\n .map((e) => {\n const d = e.data as unknown as DraftData;\n return { id: e.id, text: d.text, format: d.format, status: d.status, schedule_at: d.schedule_at };\n })\n .filter((d): d is typeof d & { schedule_at: string } =>\n !!d.schedule_at && (d.status === \"draft\" || d.status === \"approved\" || d.status === \"in_review\"))\n .sort((a, b) => (a.schedule_at > b.schedule_at ? 1 : -1));\n\n return { drafts: pending, scheduled };\n });\n\n // Cross-plugin event subscriptions (logging only for v1)\n ctx.events.on(`plugin.${ENTITY_TYPES.draft}` as never, async () => {\n // placeholder \u2014 can't subscribe to x-intelligence events without the exact\n // event type string at compile time. Wire this up at deployment time.\n });\n\n ctx.logger.info(\"X Publishing plugin initialized\");\n },\n\n async onHealth() {\n if (!pluginCtx) return { status: \"error\" as const, message: \"Plugin not initialized\" };\n\n const config = await getConfig(pluginCtx);\n const accounts = config.accounts || {};\n const handles = Object.keys(accounts);\n\n if (handles.length === 0) {\n return { status: \"error\" as const, message: \"No accounts configured\" };\n }\n\n let status: \"ok\" | \"degraded\" | \"error\" = \"ok\";\n const issues: string[] = [];\n const accountDetails: Record<string, unknown> = {};\n\n for (const handle of handles) {\n const detail: Record<string, unknown> = { role: accounts[handle]!.role };\n try {\n const tokens = await getTokens(pluginCtx, handle);\n const tokenOk = tokens.expires_at > Date.now();\n const minutesLeft = Math.round((tokens.expires_at - Date.now()) / 60000);\n detail.token = tokenOk ? `valid (${minutesLeft}m remaining)` : \"expired\";\n if (!tokenOk) {\n if (status === \"ok\") status = \"degraded\";\n issues.push(`@${handle} token expired`);\n }\n } catch {\n status = \"error\";\n issues.push(`@${handle} no tokens`);\n detail.token = \"not configured\";\n }\n\n try {\n const raw = await pluginCtx.state.get(stateKey(accountStateKey(STATE_KEYS.rateLimits, handle)));\n if (raw) {\n const limits = raw as unknown as RateLimitState;\n detail.rate_limits = { remaining: limits.post_tweets?.remaining ?? \"unknown\", daily: limits.daily_posts ?? 0 };\n if (limits.post_tweets && limits.post_tweets.remaining === 0 && limits.post_tweets.reset_at > Date.now()) {\n if (status === \"ok\") status = \"degraded\";\n issues.push(`@${handle} rate limited`);\n }\n }\n } catch { /* no rate limit data yet */ }\n\n accountDetails[handle] = detail;\n }\n\n const message = issues.length > 0 ? issues.join(\"; \") : `All ${handles.length} account(s) operational`;\n return { status, message, details: { accounts: accountDetails } };\n },\n\n async onValidateConfig(config: Record<string, unknown>) {\n const warnings: string[] = [];\n const errors: string[] = [];\n\n const accounts = (config.accounts || {}) as Record<string, { x_handle?: string; x_user_id?: string }>;\n const handles = Object.keys(accounts);\n\n if (handles.length === 0) {\n errors.push(\"At least one account is required in accounts map\");\n }\n\n const defaultAcct = config.default_account as string | undefined;\n if (defaultAcct && handles.length > 0 && !accounts[defaultAcct]) {\n errors.push(`default_account \"${defaultAcct}\" is not in the accounts map. Available: ${handles.join(\", \")}`);\n }\n\n for (const handle of handles) {\n const acct = accounts[handle]!;\n if (!acct.x_handle) errors.push(`Account ${handle}: x_handle is required`);\n if (!acct.x_user_id) errors.push(`Account ${handle}: x_user_id is required`);\n }\n\n if (pluginCtx) {\n const clientIdRef = (config.oauth_client_id_ref as string) || DEFAULT_CONFIG.oauth_client_id_ref;\n const clientSecretRef = (config.oauth_client_secret_ref as string) || DEFAULT_CONFIG.oauth_client_secret_ref;\n\n try {\n await pluginCtx.secrets.resolve(clientIdRef);\n } catch {\n errors.push(\"Could not resolve oauth_client_id_ref secret\");\n }\n\n try {\n await pluginCtx.secrets.resolve(clientSecretRef);\n } catch {\n errors.push(\"Could not resolve oauth_client_secret_ref secret\");\n }\n\n for (const handle of handles) {\n try {\n await getTokens(pluginCtx, handle);\n } catch {\n warnings.push(`No OAuth tokens for @${handle} \u2014 run setup-oauth tool`);\n }\n }\n }\n\n return { ok: errors.length === 0, warnings, errors };\n },\n});\n\nexport default plugin;\nrunWorker(plugin, import.meta.url);\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["plugin", "stateKey", "stateKey"]
|
|
4
|
+
"sourcesContent": [null, null, null, "export const PLUGIN_ID = \"peak6-labs.x-publishing\";\nexport const PLUGIN_VERSION = \"0.2.3\";\n\nexport const TOOL_NAMES = {\n draftPost: \"draft-post\",\n updateDraft: \"update-draft\",\n publishPost: \"publish-post\",\n replyToTweet: \"reply-to-tweet\",\n quoteTweet: \"quote-tweet\",\n repost: \"repost\",\n schedulePost: \"schedule-post\",\n publishThread: \"publish-thread\",\n draftThread: \"draft-thread\",\n getDrafts: \"get-drafts\",\n getSchedule: \"get-schedule\",\n getPostMetrics: \"get-post-metrics\",\n getAccountStatus: \"get-account-status\",\n setupOauth: \"setup-oauth\",\n} as const;\n\nexport const JOB_KEYS = {\n tokenRefresh: \"token-refresh\",\n publishScheduled: \"publish-scheduled\",\n metricsCapture: \"metrics-capture\",\n staleDraftCleanup: \"stale-draft-cleanup\",\n} as const;\n\nexport const ENTITY_TYPES = {\n draft: \"draft\",\n publishedPost: \"published-post\",\n} as const;\n\nexport const EVENT_NAMES = {\n postPublished: \"post.published\",\n draftCreated: \"draft.created\",\n approvalRequired: \"approval.required\",\n postEngagementMilestone: \"post.engagement-milestone\",\n threadPublished: \"thread.published\",\n} as const;\n\nexport const STATE_KEYS = {\n oauthTokens: \"oauth_tokens\",\n rateLimits: \"rate_limits\",\n} as const;\n\nexport const SLOT_IDS = {\n dashboardWidget: \"x-publishing-dashboard\",\n settingsPage: \"x-publishing-settings\",\n contentPage: \"x-publishing-content\",\n} as const;\n\nexport const EXPORT_NAMES = {\n dashboardWidget: \"DashboardWidget\",\n settingsPage: \"SettingsPage\",\n contentPage: \"ContentPage\",\n} as const;\n\nexport type ApprovalMode = \"required\" | \"optional\" | \"none\";\n\nexport const DEFAULT_APPROVAL_MODES = {\n posts: \"none\" as ApprovalMode,\n replies: \"none\" as ApprovalMode,\n quotes: \"none\" as ApprovalMode,\n reposts: \"none\" as ApprovalMode,\n scheduled: \"required\" as ApprovalMode,\n};\n\nexport const DEFAULT_CONFIG = {\n company_id: \"\",\n oauth_client_id_ref: \"X_OAUTH_CLIENT_ID\",\n oauth_client_secret_ref: \"X_OAUTH_CLIENT_SECRET\",\n default_account: \"\",\n accounts: {} as Record<string, { x_handle: string; x_user_id: string; role: \"hub\" | \"spoke\"; approval_modes: typeof DEFAULT_APPROVAL_MODES }>,\n daily_post_limit: 25,\n engagement_milestones: [50, 100, 500, 1000],\n metrics_capture_lookback_days: 7,\n alert_agents: [] as Array<{ agentId: string; memoryFile: string | null }>,\n} as const;\n\n/** Build per-account state key */\nexport function accountStateKey(base: string, handle: string): string {\n return `${base}:${handle}`;\n}\n", "import type { PluginContext } from \"@paperclipai/plugin-sdk\";\nimport { STATE_KEYS, accountStateKey } from \"../constants.js\";\nimport type { PublishingConfig, TokenState } from \"../types.js\";\n\nconst REFRESH_BUFFER_MS = 5 * 60 * 1000; // 5 minutes\n\nfunction stateKey(key: string) {\n return { scopeKind: \"instance\" as const, stateKey: key };\n}\n\nexport async function getTokens(ctx: PluginContext, handle: string): Promise<TokenState> {\n const raw = await ctx.state.get(stateKey(accountStateKey(STATE_KEYS.oauthTokens, handle)));\n if (!raw) throw new Error(`No OAuth tokens in state for @${handle}`);\n return raw as unknown as TokenState;\n}\n\nexport async function setTokens(ctx: PluginContext, handle: string, tokens: TokenState): Promise<void> {\n await ctx.state.set(\n stateKey(accountStateKey(STATE_KEYS.oauthTokens, handle)),\n tokens as unknown as Record<string, unknown>,\n );\n}\n\nexport async function refreshTokens(ctx: PluginContext, config: PublishingConfig, handle: string): Promise<TokenState> {\n const current = await getTokens(ctx, handle);\n const clientId = await ctx.secrets.resolve(config.oauth_client_id_ref);\n const clientSecret = await ctx.secrets.resolve(config.oauth_client_secret_ref);\n\n const resp = await ctx.http.fetch(\"https://api.x.com/2/oauth2/token\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n Authorization: `Basic ${btoa(`${clientId}:${clientSecret}`)}`,\n },\n body: new URLSearchParams({\n grant_type: \"refresh_token\",\n refresh_token: current.refresh_token,\n }).toString(),\n });\n\n if (!resp.ok) {\n const text = await resp.text();\n throw new Error(`Token refresh failed for @${handle}: HTTP ${resp.status} \u2014 ${text}`);\n }\n\n const body = (await resp.json()) as {\n access_token: string;\n refresh_token: string;\n expires_in: number;\n token_type: string;\n };\n\n const newTokens: TokenState = {\n access_token: body.access_token,\n refresh_token: body.refresh_token,\n expires_at: Date.now() + body.expires_in * 1000,\n };\n\n await setTokens(ctx, handle, newTokens);\n return newTokens;\n}\n\nexport async function getValidAccessToken(ctx: PluginContext, config: PublishingConfig, handle: string): Promise<string> {\n const tokens = await getTokens(ctx, handle);\n\n if (tokens.expires_at - Date.now() < REFRESH_BUFFER_MS) {\n const refreshed = await refreshTokens(ctx, config, handle);\n return refreshed.access_token;\n }\n\n return tokens.access_token;\n}\n", "import type { PluginContext } from \"@paperclipai/plugin-sdk\";\nimport type { RateLimitHeaders } from \"../types.js\";\n\nfunction parseRateLimitHeaders(headers: Headers): RateLimitHeaders {\n const remaining = parseInt(headers.get(\"x-rate-limit-remaining\") || \"99\", 10);\n const resetEpoch = parseInt(headers.get(\"x-rate-limit-reset\") || \"0\", 10);\n return {\n remaining,\n reset_at: resetEpoch * 1000, // X API returns epoch seconds\n };\n}\n\nasync function withRetry<T>(fn: () => Promise<T>, maxRetries = 2): Promise<T> {\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n return await fn();\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n if (attempt < maxRetries && message.includes(\"429\")) {\n const backoffMs = Math.pow(2, attempt + 1) * 1000;\n await new Promise((r) => setTimeout(r, backoffMs));\n continue;\n }\n throw err;\n }\n }\n throw new Error(\"Unreachable\");\n}\n\ntype HttpClient = PluginContext[\"http\"];\n\nexport async function createTweet(\n http: HttpClient,\n token: string,\n params: { text: string; reply_to?: string; quote_tweet_id?: string; media_ids?: string[] },\n): Promise<{ data: { id: string; text: string }; rateLimit: RateLimitHeaders }> {\n return withRetry(async () => {\n const body: Record<string, unknown> = { text: params.text };\n\n if (params.reply_to) {\n body.reply = { in_reply_to_tweet_id: params.reply_to };\n }\n if (params.quote_tweet_id) {\n body.quote_tweet_id = params.quote_tweet_id;\n }\n if (params.media_ids && params.media_ids.length > 0) {\n body.media = { media_ids: params.media_ids };\n }\n\n const resp = await http.fetch(\"https://api.x.com/2/tweets\", {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(body),\n });\n\n if (resp.status === 429) {\n throw new Error(\"429 Rate limited\");\n }\n\n if (resp.status !== 201) {\n const text = await resp.text();\n throw new Error(`Create tweet failed: HTTP ${resp.status} \u2014 ${text}`);\n }\n\n const json = (await resp.json()) as { data: { id: string; text: string } };\n return {\n data: json.data,\n rateLimit: parseRateLimitHeaders(resp.headers),\n };\n });\n}\n\nexport async function deleteTweet(\n http: HttpClient,\n token: string,\n tweetId: string,\n): Promise<{ data: { deleted: boolean }; rateLimit: RateLimitHeaders }> {\n return withRetry(async () => {\n const resp = await http.fetch(`https://api.x.com/2/tweets/${tweetId}`, {\n method: \"DELETE\",\n headers: { Authorization: `Bearer ${token}` },\n });\n\n if (resp.status === 429) {\n throw new Error(\"429 Rate limited\");\n }\n\n if (resp.status !== 200) {\n const text = await resp.text();\n throw new Error(`Delete tweet failed: HTTP ${resp.status} \u2014 ${text}`);\n }\n\n const json = (await resp.json()) as { data: { deleted: boolean } };\n return {\n data: json.data,\n rateLimit: parseRateLimitHeaders(resp.headers),\n };\n });\n}\n\nexport async function repost(\n http: HttpClient,\n token: string,\n userId: string,\n tweetId: string,\n): Promise<{ data: { retweeted: boolean }; rateLimit: RateLimitHeaders }> {\n return withRetry(async () => {\n const resp = await http.fetch(`https://api.x.com/2/users/${userId}/retweets`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({ tweet_id: tweetId }),\n });\n\n if (resp.status === 429) {\n throw new Error(\"429 Rate limited\");\n }\n\n if (resp.status !== 200) {\n const text = await resp.text();\n throw new Error(`Repost failed: HTTP ${resp.status} \u2014 ${text}`);\n }\n\n const json = (await resp.json()) as { data: { retweeted: boolean } };\n return {\n data: json.data,\n rateLimit: parseRateLimitHeaders(resp.headers),\n };\n });\n}\n\nexport async function undoRepost(\n http: HttpClient,\n token: string,\n userId: string,\n tweetId: string,\n): Promise<{ data: { retweeted: boolean }; rateLimit: RateLimitHeaders }> {\n return withRetry(async () => {\n const resp = await http.fetch(`https://api.x.com/2/users/${userId}/retweets/${tweetId}`, {\n method: \"DELETE\",\n headers: { Authorization: `Bearer ${token}` },\n });\n\n if (resp.status === 429) {\n throw new Error(\"429 Rate limited\");\n }\n\n if (resp.status !== 200) {\n const text = await resp.text();\n throw new Error(`Undo repost failed: HTTP ${resp.status} \u2014 ${text}`);\n }\n\n const json = (await resp.json()) as { data: { retweeted: boolean } };\n return {\n data: json.data,\n rateLimit: parseRateLimitHeaders(resp.headers),\n };\n });\n}\n", "import type { PluginContext } from \"@paperclipai/plugin-sdk\";\nimport { STATE_KEYS, accountStateKey } from \"../constants.js\";\nimport type { RateLimitHeaders, RateLimitState } from \"../types.js\";\n\nfunction stateKey(key: string) {\n return { scopeKind: \"instance\" as const, stateKey: key };\n}\n\nconst DEFAULT_STATE: RateLimitState = {\n post_tweets: { remaining: 99, reset_at: 0 },\n delete_tweets: { remaining: 99, reset_at: 0 },\n retweets: { remaining: 99, reset_at: 0 },\n daily_posts: 0,\n daily_reset_at: 0,\n};\n\nasync function getRateLimitState(ctx: PluginContext, handle: string): Promise<RateLimitState> {\n const raw = await ctx.state.get(stateKey(accountStateKey(STATE_KEYS.rateLimits, handle)));\n if (!raw) return { ...DEFAULT_STATE };\n const state = raw as unknown as RateLimitState;\n\n if (state.daily_reset_at && Date.now() > state.daily_reset_at) {\n state.daily_posts = 0;\n state.daily_reset_at = getNextMidnightMs();\n }\n\n return state;\n}\n\nfunction getNextMidnightMs(): number {\n const now = new Date();\n const tomorrow = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1);\n return tomorrow.getTime();\n}\n\nexport async function updateRateLimits(\n ctx: PluginContext,\n handle: string,\n endpoint: \"post_tweets\" | \"delete_tweets\" | \"retweets\",\n headers: RateLimitHeaders,\n): Promise<void> {\n const state = await getRateLimitState(ctx, handle);\n\n state[endpoint] = {\n remaining: headers.remaining,\n reset_at: headers.reset_at,\n };\n\n if (endpoint === \"post_tweets\") {\n state.daily_posts++;\n if (!state.daily_reset_at) {\n state.daily_reset_at = getNextMidnightMs();\n }\n }\n\n await ctx.state.set(\n stateKey(accountStateKey(STATE_KEYS.rateLimits, handle)),\n state as unknown as Record<string, unknown>,\n );\n}\n\nexport async function checkRateLimit(\n ctx: PluginContext,\n handle: string,\n endpoint: \"post_tweets\" | \"delete_tweets\" | \"retweets\",\n dailyLimit?: number,\n): Promise<{ ok: boolean; reason?: string }> {\n const state = await getRateLimitState(ctx, handle);\n const limit = state[endpoint];\n\n if (limit.remaining <= 0 && limit.reset_at > Date.now()) {\n const resetIn = Math.ceil((limit.reset_at - Date.now()) / 60000);\n return { ok: false, reason: `Rate limit exhausted for ${endpoint} on @${handle}. Resets in ${resetIn}m.` };\n }\n\n if (dailyLimit && endpoint === \"post_tweets\" && state.daily_posts >= dailyLimit) {\n return { ok: false, reason: `Daily post limit (${dailyLimit}) reached for @${handle}.` };\n }\n\n return { ok: true };\n}\n", "import type { PluginContext } from \"@paperclipai/plugin-sdk\";\nimport type { ApprovalModes, PublishingConfig, DraftData } from \"../types.js\";\nimport { ENTITY_TYPES, EVENT_NAMES, DEFAULT_APPROVAL_MODES } from \"../constants.js\";\n\ntype ContentType = \"posts\" | \"replies\" | \"quotes\" | \"reposts\" | \"scheduled\";\n\ninterface ApprovalResult {\n allowed: boolean;\n reason?: string;\n}\n\nexport async function checkApproval(\n ctx: PluginContext,\n config: PublishingConfig,\n contentType: ContentType,\n draftId?: string,\n approvalModes?: ApprovalModes,\n): Promise<ApprovalResult> {\n const modes = approvalModes || DEFAULT_APPROVAL_MODES;\n const mode = modes[contentType];\n\n if (mode === \"none\") {\n return { allowed: true };\n }\n\n if (mode === \"optional\") {\n ctx.logger.info(`Approval optional for ${contentType}, proceeding`);\n return { allowed: true };\n }\n\n // mode === \"required\"\n if (!draftId) {\n const issue = await ctx.issues.create({\n companyId: config.company_id,\n title: `Approval required for ${contentType}`,\n description: `Content type \"${contentType}\" requires approval but no draft was provided for review.\\n\\nCreate a draft first, then have it approved before publishing.`,\n });\n await ctx.issues.update(issue.id, { status: \"todo\" as const }, config.company_id);\n\n await ctx.events.emit(EVENT_NAMES.approvalRequired, config.company_id, {\n content_type: contentType,\n reason: \"No draft provided for required approval\",\n });\n\n return { allowed: false, reason: `Approval required for ${contentType}. Create a draft and get it approved first.` };\n }\n\n // Find draft by ID\n const allDrafts = await ctx.entities.list({ entityType: ENTITY_TYPES.draft, limit: 500 });\n const entity = allDrafts.find((e) => e.id === draftId);\n if (!entity) {\n return { allowed: false, reason: `Draft ${draftId} not found.` };\n }\n\n const draft = entity.data as unknown as DraftData;\n if (draft.status === \"approved\") {\n return { allowed: true };\n }\n\n // Draft exists but not approved \u2014 move to in_review\n if (draft.status !== \"in_review\") {\n draft.status = \"in_review\";\n const issue = await ctx.issues.create({\n companyId: config.company_id,\n title: `Review draft: ${draft.text.slice(0, 60)}`,\n description: `Draft ID: ${draftId}\\nFormat: ${draft.format}\\n\\nText:\\n${draft.text}${draft.thread_tweets ? \"\\n\\nThread:\\n\" + draft.thread_tweets.join(\"\\n---\\n\") : \"\"}`,\n });\n await ctx.issues.update(issue.id, { status: \"todo\" as const }, config.company_id);\n\n draft.review_issue_id = issue.id;\n await ctx.entities.upsert({\n entityType: ENTITY_TYPES.draft,\n scopeKind: \"instance\",\n externalId: entity.externalId ?? undefined,\n title: entity.title ?? draft.text.slice(0, 60),\n data: draft as unknown as Record<string, unknown>,\n });\n\n await ctx.events.emit(EVENT_NAMES.approvalRequired, config.company_id, {\n draft_id: draftId,\n content_type: contentType,\n reason: \"Draft submitted for review\",\n });\n }\n\n return { allowed: false, reason: `Draft ${draftId} is ${draft.status}. Approval required before publishing.` };\n}\n", "import type { PluginContext } from \"@paperclipai/plugin-sdk\";\nimport { ENTITY_TYPES } from \"../constants.js\";\nimport type { ContentMetadata, PublishedPostData } from \"../types.js\";\nimport { createTweet } from \"./x-api-write-client.js\";\nimport { updateRateLimits } from \"./rate-limiter.js\";\n\nconst MAX_RETRIES = 3;\n\nexport interface ThreadResult {\n tweetIds: string[];\n partial: boolean;\n}\n\nexport async function publishThread(\n ctx: PluginContext,\n token: string,\n handle: string,\n tweets: string[],\n metadata: ContentMetadata,\n companyId: string,\n): Promise<ThreadResult> {\n const tweetIds: string[] = [];\n let replyTo: string | undefined;\n\n for (let i = 0; i < tweets.length; i++) {\n const text = tweets[i]!;\n let posted = false;\n\n for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {\n try {\n const result = await createTweet(ctx.http, token, {\n text,\n reply_to: replyTo,\n });\n await updateRateLimits(ctx, handle, \"post_tweets\", result.rateLimit);\n\n tweetIds.push(result.data.id);\n replyTo = result.data.id;\n\n const published: PublishedPostData = {\n tweet_id: result.data.id,\n account: handle,\n text: result.data.text,\n published_at: new Date().toISOString(),\n format: \"thread\",\n thread_tweet_ids: tweetIds.slice(),\n metadata,\n };\n\n await ctx.entities.upsert({\n entityType: ENTITY_TYPES.publishedPost,\n scopeKind: \"instance\",\n externalId: result.data.id,\n title: `Thread ${i + 1}/${tweets.length}: ${text.slice(0, 40)}`,\n data: published as unknown as Record<string, unknown>,\n });\n\n posted = true;\n break;\n } catch (err) {\n ctx.logger.error(`Thread tweet ${i + 1}/${tweets.length} attempt ${attempt + 1} failed`, { error: String(err) });\n if (attempt < MAX_RETRIES - 1) {\n await new Promise((r) => setTimeout(r, Math.pow(2, attempt + 1) * 1000));\n }\n }\n }\n\n if (!posted) {\n const issue = await ctx.issues.create({\n companyId,\n title: `Thread publish failed at tweet ${i + 1}/${tweets.length}`,\n description: `Thread was partially published.\\n\\nPublished tweet IDs: ${tweetIds.join(\", \")}\\n\\nFailed tweet text: ${text}\\n\\nRemaining tweets: ${tweets.length - i}`,\n });\n await ctx.issues.update(issue.id, { status: \"todo\" as const }, companyId);\n\n return { tweetIds, partial: true };\n }\n }\n\n return { tweetIds, partial: false };\n}\n", "import {\n definePlugin,\n runWorker,\n type PluginContext,\n type PluginJobContext,\n type ToolResult,\n} from \"@paperclipai/plugin-sdk\";\nimport {\n DEFAULT_CONFIG,\n accountStateKey,\n ENTITY_TYPES,\n EVENT_NAMES,\n JOB_KEYS,\n STATE_KEYS,\n TOOL_NAMES,\n} from \"./constants.js\";\nimport type {\n AccountConfig,\n PublishingConfig,\n TokenState,\n DraftData,\n PublishedPostData,\n RateLimitState,\n} from \"./types.js\";\nimport { getValidAccessToken, getTokens, setTokens, refreshTokens } from \"./pipeline/oauth-manager.js\";\nimport { createTweet } from \"./pipeline/x-api-write-client.js\";\nimport { repost as apiRepost } from \"./pipeline/x-api-write-client.js\";\nimport { updateRateLimits } from \"./pipeline/rate-limiter.js\";\nimport { checkApproval } from \"./pipeline/approval-gate.js\";\nimport { publishThread } from \"./pipeline/thread-publisher.js\";\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction stateKey(key: string) {\n return { scopeKind: \"instance\" as const, stateKey: key };\n}\n\nasync function getConfig(ctx: PluginContext): Promise<PublishingConfig> {\n const raw = await ctx.config.get();\n return { ...DEFAULT_CONFIG, ...raw } as unknown as PublishingConfig;\n}\n\n/** Resolve which account to use. Returns the AccountConfig or an error string. */\nfunction resolveAccount(\n config: PublishingConfig,\n handle?: string,\n): { ok: true; handle: string; account: AccountConfig } | { ok: false; error: string } {\n const accounts = config.accounts || {};\n const handles = Object.keys(accounts);\n\n if (handles.length === 0) {\n return { ok: false, error: \"No accounts configured.\" };\n }\n\n const target = handle || config.default_account || handles[0]!;\n const account = accounts[target];\n if (!account) {\n return { ok: false, error: `Account @${target} not found in config. Available: ${handles.join(\", \")}` };\n }\n\n return { ok: true, handle: target, account };\n}\n\ninterface EntityRecord {\n id: string;\n entityType: string;\n externalId: string | null;\n title: string | null;\n status: string | null;\n data: Record<string, unknown>;\n createdAt: string;\n updatedAt: string;\n}\n\nfunction findEntityById<T>(entities: EntityRecord[], id: string): { id: string; data: T; raw: EntityRecord } | null {\n const found = entities.find((e) => e.id === id);\n if (!found) return null;\n return { id: found.id, data: found.data as unknown as T, raw: found };\n}\n\n// ---------------------------------------------------------------------------\n// Tool handlers\n// ---------------------------------------------------------------------------\n\nasync function handleSetupOauth(ctx: PluginContext, params: Record<string, unknown>): Promise<ToolResult> {\n const handle = params.account as string;\n if (!handle) return { error: \"account param is required (X handle to store tokens for).\" };\n\n const config = await getConfig(ctx);\n const resolved = resolveAccount(config, handle);\n if (!resolved.ok) return { error: resolved.error };\n\n const accessToken = params.access_token as string;\n const refreshToken = params.refresh_token as string;\n const expiresIn = (params.expires_in as number) || 7200;\n\n const tokenState: TokenState = {\n access_token: accessToken,\n refresh_token: refreshToken,\n expires_at: Date.now() + expiresIn * 1000,\n };\n await setTokens(ctx, handle, tokenState);\n\n return { content: `OAuth tokens stored for @${handle}. Expires at ${new Date(tokenState.expires_at).toISOString()}.` };\n}\n\nasync function handleDraftPost(ctx: PluginContext, params: Record<string, unknown>): Promise<ToolResult> {\n const text = params.text as string;\n if (text.length > 280) {\n return { error: `Tweet text exceeds 280 characters (${text.length}).` };\n }\n\n const config = await getConfig(ctx);\n const format = (params.format as string) || \"single\";\n const metadata = (params.metadata as DraftData[\"metadata\"]) || {};\n\n const draft: DraftData = {\n text,\n format: format as DraftData[\"format\"],\n account: (params.account as string | undefined) || config.default_account || undefined,\n reply_to_tweet_id: params.reply_to_tweet_id as string | undefined,\n quote_tweet_id: params.quote_tweet_id as string | undefined,\n schedule_at: params.schedule_at as string | undefined,\n status: \"draft\",\n metadata,\n };\n\n const entity = await ctx.entities.upsert({\n entityType: ENTITY_TYPES.draft,\n scopeKind: \"instance\",\n title: text.slice(0, 60),\n data: draft as unknown as Record<string, unknown>,\n });\n\n await ctx.events.emit(EVENT_NAMES.draftCreated, config.company_id, {\n draft_id: entity.id,\n format,\n metadata,\n });\n\n return { content: JSON.stringify({ draft_id: entity.id, status: \"draft\", format }) };\n}\n\nasync function handleDraftThread(ctx: PluginContext, params: Record<string, unknown>): Promise<ToolResult> {\n const threadTweets = params.thread_tweets as string[];\n if (!threadTweets || threadTweets.length < 2) {\n return { error: \"Thread must have at least 2 tweets.\" };\n }\n\n for (let i = 0; i < threadTweets.length; i++) {\n if (threadTweets[i]!.length > 280) {\n return { error: `Tweet ${i + 1} exceeds 280 characters (${threadTweets[i]!.length}).` };\n }\n }\n\n const config = await getConfig(ctx);\n const metadata = (params.metadata as DraftData[\"metadata\"]) || {};\n const draft: DraftData = {\n text: threadTweets[0]!,\n format: \"thread\",\n account: (params.account as string | undefined) || config.default_account || undefined,\n thread_tweets: threadTweets,\n schedule_at: params.schedule_at as string | undefined,\n status: \"draft\",\n metadata,\n };\n\n const entity = await ctx.entities.upsert({\n entityType: ENTITY_TYPES.draft,\n scopeKind: \"instance\",\n title: `Thread: ${threadTweets[0]!.slice(0, 50)}`,\n data: draft as unknown as Record<string, unknown>,\n });\n\n await ctx.events.emit(EVENT_NAMES.draftCreated, config.company_id, {\n draft_id: entity.id,\n format: \"thread\",\n metadata,\n });\n\n return { content: JSON.stringify({ draft_id: entity.id, status: \"draft\", format: \"thread\", tweet_count: threadTweets.length }) };\n}\n\nasync function handleUpdateDraft(ctx: PluginContext, params: Record<string, unknown>): Promise<ToolResult> {\n const draftId = params.draft_id as string;\n const entities = await ctx.entities.list({ entityType: ENTITY_TYPES.draft, limit: 500 });\n const match = findEntityById<DraftData>(entities, draftId);\n if (!match) return { error: `Draft ${draftId} not found.` };\n\n const data = match.data;\n if (params.text !== undefined) data.text = params.text as string;\n if (params.thread_tweets !== undefined) data.thread_tweets = params.thread_tweets as string[];\n if (params.schedule_at !== undefined) data.schedule_at = params.schedule_at as string;\n if (params.metadata !== undefined) data.metadata = { ...data.metadata, ...(params.metadata as DraftData[\"metadata\"]) };\n data.status = \"draft\"; // reset to draft on edit\n\n await ctx.entities.upsert({\n entityType: ENTITY_TYPES.draft,\n scopeKind: \"instance\",\n externalId: match.raw.externalId ?? undefined,\n title: data.text.slice(0, 60),\n data: data as unknown as Record<string, unknown>,\n });\n\n return { content: JSON.stringify({ draft_id: draftId, status: \"draft\", updated: true }) };\n}\n\nasync function handlePublishPost(ctx: PluginContext, params: Record<string, unknown>): Promise<ToolResult> {\n const config = await getConfig(ctx);\n const resolved = resolveAccount(config, params.account as string | undefined);\n if (!resolved.ok) return { error: resolved.error };\n const { handle, account } = resolved;\n\n let text = params.text as string | undefined;\n let metadata = (params.metadata as PublishedPostData[\"metadata\"]) || {};\n const draftId = params.draft_id as string | undefined;\n\n if (draftId) {\n const entities = await ctx.entities.list({ entityType: ENTITY_TYPES.draft, limit: 500 });\n const match = findEntityById<DraftData>(entities, draftId);\n if (!match) return { error: `Draft ${draftId} not found.` };\n text = match.data.text;\n metadata = { ...match.data.metadata, ...metadata };\n }\n\n if (!text) return { error: \"No text provided and no draft_id.\" };\n\n const approval = await checkApproval(ctx, config, \"posts\", draftId, account.approval_modes);\n if (!approval.allowed) return { error: `Blocked: ${approval.reason}` };\n\n const token = await getValidAccessToken(ctx, config, handle);\n const result = await createTweet(ctx.http, token, { text });\n await updateRateLimits(ctx, handle, \"post_tweets\", result.rateLimit);\n\n const published: PublishedPostData = {\n tweet_id: result.data.id,\n account: handle,\n text: result.data.text,\n published_at: new Date().toISOString(),\n draft_id: draftId,\n format: \"single\",\n metadata,\n };\n\n await ctx.entities.upsert({\n entityType: ENTITY_TYPES.publishedPost,\n scopeKind: \"instance\",\n externalId: result.data.id,\n title: text.slice(0, 60),\n data: published as unknown as Record<string, unknown>,\n });\n\n await ctx.events.emit(EVENT_NAMES.postPublished, config.company_id, {\n tweet_id: result.data.id, text, format: \"single\", metadata,\n });\n\n return { content: JSON.stringify({ tweet_id: result.data.id, text: result.data.text, status: \"published\" }) };\n}\n\nasync function handleReplyToTweet(ctx: PluginContext, params: Record<string, unknown>): Promise<ToolResult> {\n const config = await getConfig(ctx);\n const resolved = resolveAccount(config, params.account as string | undefined);\n if (!resolved.ok) return { error: resolved.error };\n const { handle, account } = resolved;\n\n const tweetId = params.tweet_id as string;\n const text = params.text as string;\n const metadata = (params.metadata as PublishedPostData[\"metadata\"]) || {};\n\n const approval = await checkApproval(ctx, config, \"replies\", params.draft_id as string | undefined, account.approval_modes);\n if (!approval.allowed) return { error: `Blocked: ${approval.reason}` };\n\n const token = await getValidAccessToken(ctx, config, handle);\n const result = await createTweet(ctx.http, token, { text, reply_to: tweetId });\n await updateRateLimits(ctx, handle, \"post_tweets\", result.rateLimit);\n\n const published: PublishedPostData = {\n tweet_id: result.data.id,\n account: handle,\n text: result.data.text,\n published_at: new Date().toISOString(),\n draft_id: params.draft_id as string | undefined,\n format: \"reply\",\n metadata: { ...metadata, source_tweet_id: tweetId },\n };\n\n await ctx.entities.upsert({\n entityType: ENTITY_TYPES.publishedPost,\n scopeKind: \"instance\",\n externalId: result.data.id,\n title: `Reply: ${text.slice(0, 50)}`,\n data: published as unknown as Record<string, unknown>,\n });\n\n await ctx.events.emit(EVENT_NAMES.postPublished, config.company_id, {\n tweet_id: result.data.id, text, format: \"reply\", metadata: published.metadata,\n });\n\n return { content: JSON.stringify({ tweet_id: result.data.id, text: result.data.text, status: \"published\", reply_to: tweetId }) };\n}\n\nasync function handleQuoteTweet(ctx: PluginContext, params: Record<string, unknown>): Promise<ToolResult> {\n const config = await getConfig(ctx);\n const resolved = resolveAccount(config, params.account as string | undefined);\n if (!resolved.ok) return { error: resolved.error };\n const { handle, account } = resolved;\n\n const tweetId = params.tweet_id as string;\n const text = params.text as string;\n const metadata = (params.metadata as PublishedPostData[\"metadata\"]) || {};\n\n const approval = await checkApproval(ctx, config, \"quotes\", params.draft_id as string | undefined, account.approval_modes);\n if (!approval.allowed) return { error: `Blocked: ${approval.reason}` };\n\n const token = await getValidAccessToken(ctx, config, handle);\n const result = await createTweet(ctx.http, token, { text, quote_tweet_id: tweetId });\n await updateRateLimits(ctx, handle, \"post_tweets\", result.rateLimit);\n\n const published: PublishedPostData = {\n tweet_id: result.data.id,\n account: handle,\n text: result.data.text,\n published_at: new Date().toISOString(),\n draft_id: params.draft_id as string | undefined,\n format: \"quote\",\n metadata: { ...metadata, source_tweet_id: tweetId },\n };\n\n await ctx.entities.upsert({\n entityType: ENTITY_TYPES.publishedPost,\n scopeKind: \"instance\",\n externalId: result.data.id,\n title: `Quote: ${text.slice(0, 50)}`,\n data: published as unknown as Record<string, unknown>,\n });\n\n await ctx.events.emit(EVENT_NAMES.postPublished, config.company_id, {\n tweet_id: result.data.id, text, format: \"quote\", metadata: published.metadata,\n });\n\n return { content: JSON.stringify({ tweet_id: result.data.id, text: result.data.text, status: \"published\", quoted: tweetId }) };\n}\n\nasync function handleRepost(ctx: PluginContext, params: Record<string, unknown>): Promise<ToolResult> {\n const config = await getConfig(ctx);\n const resolved = resolveAccount(config, params.account as string | undefined);\n if (!resolved.ok) return { error: resolved.error };\n const { handle, account } = resolved;\n\n const tweetId = params.tweet_id as string;\n\n const approval = await checkApproval(ctx, config, \"reposts\", params.draft_id as string | undefined, account.approval_modes);\n if (!approval.allowed) return { error: `Blocked: ${approval.reason}` };\n\n const token = await getValidAccessToken(ctx, config, handle);\n const result = await apiRepost(ctx.http, token, account.x_user_id, tweetId);\n await updateRateLimits(ctx, handle, \"retweets\", result.rateLimit);\n\n const published: PublishedPostData = {\n tweet_id: tweetId,\n account: handle,\n text: \"\",\n published_at: new Date().toISOString(),\n draft_id: params.draft_id as string | undefined,\n format: \"repost\",\n metadata: { source_tweet_id: tweetId },\n };\n\n await ctx.entities.upsert({\n entityType: ENTITY_TYPES.publishedPost,\n scopeKind: \"instance\",\n externalId: `repost-${tweetId}`,\n title: `Repost: ${tweetId}`,\n data: published as unknown as Record<string, unknown>,\n });\n\n await ctx.events.emit(EVENT_NAMES.postPublished, config.company_id, {\n tweet_id: tweetId, text: \"\", format: \"repost\", metadata: published.metadata,\n });\n\n return { content: JSON.stringify({ tweet_id: tweetId, status: \"reposted\" }) };\n}\n\nasync function handleSchedulePost(ctx: PluginContext, params: Record<string, unknown>): Promise<ToolResult> {\n const scheduleAt = params.schedule_at as string;\n const draftId = params.draft_id as string | undefined;\n const text = params.text as string | undefined;\n const metadata = (params.metadata as DraftData[\"metadata\"]) || {};\n\n if (draftId) {\n const entities = await ctx.entities.list({ entityType: ENTITY_TYPES.draft, limit: 500 });\n const match = findEntityById<DraftData>(entities, draftId);\n if (!match) return { error: `Draft ${draftId} not found.` };\n match.data.schedule_at = scheduleAt;\n await ctx.entities.upsert({\n entityType: ENTITY_TYPES.draft,\n scopeKind: \"instance\",\n externalId: match.raw.externalId ?? undefined,\n title: match.data.text.slice(0, 60),\n data: match.data as unknown as Record<string, unknown>,\n });\n return { content: JSON.stringify({ draft_id: draftId, schedule_at: scheduleAt, status: \"scheduled\" }) };\n }\n\n if (!text) return { error: \"Provide text or draft_id.\" };\n\n const draft: DraftData = {\n text,\n format: \"single\",\n account: (params.account as string | undefined) || config.default_account || undefined,\n schedule_at: scheduleAt,\n status: \"draft\",\n metadata,\n };\n\n const entity = await ctx.entities.upsert({\n entityType: ENTITY_TYPES.draft,\n scopeKind: \"instance\",\n title: text.slice(0, 60),\n data: draft as unknown as Record<string, unknown>,\n });\n\n return { content: JSON.stringify({ draft_id: entity.id, schedule_at: scheduleAt, status: \"scheduled\" }) };\n}\n\nasync function handlePublishThread(ctx: PluginContext, params: Record<string, unknown>): Promise<ToolResult> {\n const config = await getConfig(ctx);\n const resolved = resolveAccount(config, params.account as string | undefined);\n if (!resolved.ok) return { error: resolved.error };\n const { handle, account } = resolved;\n\n let threadTweets = params.thread_tweets as string[] | undefined;\n let metadata = (params.metadata as PublishedPostData[\"metadata\"]) || {};\n const draftId = params.draft_id as string | undefined;\n\n if (draftId) {\n const entities = await ctx.entities.list({ entityType: ENTITY_TYPES.draft, limit: 500 });\n const match = findEntityById<DraftData>(entities, draftId);\n if (!match) return { error: `Draft ${draftId} not found.` };\n threadTweets = match.data.thread_tweets;\n metadata = { ...match.data.metadata, ...metadata };\n }\n\n if (!threadTweets || threadTweets.length < 2) {\n return { error: \"Thread must have at least 2 tweets.\" };\n }\n\n const approval = await checkApproval(ctx, config, \"posts\", draftId, account.approval_modes);\n if (!approval.allowed) return { error: `Blocked: ${approval.reason}` };\n\n const token = await getValidAccessToken(ctx, config, handle);\n const result = await publishThread(ctx, token, handle, threadTweets, metadata, config.company_id);\n\n await ctx.events.emit(EVENT_NAMES.threadPublished, config.company_id, {\n tweet_ids: result.tweetIds,\n thread_length: threadTweets.length,\n partial: result.partial,\n });\n\n for (const tweetId of result.tweetIds) {\n await ctx.events.emit(EVENT_NAMES.postPublished, config.company_id, {\n tweet_id: tweetId, text: \"\", format: \"thread\", metadata,\n });\n }\n\n return { content: JSON.stringify({\n tweet_ids: result.tweetIds,\n thread_length: threadTweets.length,\n partial: result.partial,\n status: result.partial ? \"partial\" : \"published\",\n }) };\n}\n\nasync function handleGetDrafts(ctx: PluginContext, params: Record<string, unknown>): Promise<ToolResult> {\n const statusFilter = params.status as string | undefined;\n const limit = (params.limit as number) || 20;\n\n const entities = await ctx.entities.list({ entityType: ENTITY_TYPES.draft, limit: 100 });\n let drafts = entities.map((e) => ({ id: e.id, ...(e.data as unknown as DraftData) }));\n\n if (statusFilter) {\n drafts = drafts.filter((d) => d.status === statusFilter);\n }\n\n return { content: JSON.stringify(drafts.slice(0, limit)) };\n}\n\nasync function handleGetSchedule(ctx: PluginContext, params: Record<string, unknown>): Promise<ToolResult> {\n const limit = (params.limit as number) || 20;\n const entities = await ctx.entities.list({ entityType: ENTITY_TYPES.draft, limit: 100 });\n const scheduled = entities\n .map((e) => ({ id: e.id, ...(e.data as unknown as DraftData) }))\n .filter((d) => d.schedule_at && (d.status === \"draft\" || d.status === \"approved\"))\n .sort((a, b) => (a.schedule_at! > b.schedule_at! ? 1 : -1));\n\n return { content: JSON.stringify(scheduled.slice(0, limit)) };\n}\n\nasync function handleGetPostMetrics(ctx: PluginContext, params: Record<string, unknown>): Promise<ToolResult> {\n const tweetId = params.tweet_id as string;\n const entities = await ctx.entities.list({ entityType: ENTITY_TYPES.publishedPost, limit: 500 });\n const post = entities.find((e) => (e.data as unknown as PublishedPostData).tweet_id === tweetId);\n\n if (!post) return { error: `No published post found for tweet ${tweetId}.` };\n\n const data = post.data as unknown as PublishedPostData;\n return { content: JSON.stringify({\n tweet_id: data.tweet_id,\n text: data.text,\n published_at: data.published_at,\n format: data.format,\n metadata: data.metadata,\n metrics: data.metrics || null,\n }) };\n}\n\nasync function handleGetAccountStatus(ctx: PluginContext, params: Record<string, unknown>): Promise<ToolResult> {\n const config = await getConfig(ctx);\n const accounts = config.accounts || {};\n const handles = params.account ? [params.account as string] : Object.keys(accounts);\n\n const today = new Date().toISOString().split(\"T\")[0]!;\n const entities = await ctx.entities.list({ entityType: ENTITY_TYPES.publishedPost, limit: 500 });\n\n const statuses = [];\n for (const handle of handles) {\n let tokenHealth = \"unknown\";\n try {\n const tokens = await getTokens(ctx, handle);\n if (tokens.expires_at > Date.now()) {\n const minutesLeft = Math.round((tokens.expires_at - Date.now()) / 60000);\n tokenHealth = `valid (${minutesLeft}m remaining)`;\n } else {\n tokenHealth = \"expired\";\n }\n } catch {\n tokenHealth = \"no tokens stored\";\n }\n\n let rateLimits: RateLimitState | null = null;\n try {\n const raw = await ctx.state.get(stateKey(accountStateKey(STATE_KEYS.rateLimits, handle)));\n if (raw) rateLimits = raw as unknown as RateLimitState;\n } catch { /* no rate limit data yet */ }\n\n const todayCount = entities.filter((e) => {\n const data = e.data as unknown as PublishedPostData;\n return data.published_at.startsWith(today) && (!data.account || data.account === handle);\n }).length;\n\n statuses.push({\n x_handle: handle,\n role: accounts[handle]?.role || \"unknown\",\n token_health: tokenHealth,\n daily_posts: { count: todayCount, limit: config.daily_post_limit },\n rate_limits: rateLimits,\n });\n }\n\n return { content: JSON.stringify(handles.length === 1 ? statuses[0] : statuses) };\n}\n\n// ---------------------------------------------------------------------------\n// Job handlers\n// ---------------------------------------------------------------------------\n\nasync function handleTokenRefresh(ctx: PluginContext, _job: PluginJobContext): Promise<void> {\n const config = await getConfig(ctx);\n const handles = Object.keys(config.accounts || {});\n\n for (const handle of handles) {\n try {\n await refreshTokens(ctx, config, handle);\n ctx.logger.info(`Token refresh succeeded for @${handle}`);\n } catch (err) {\n ctx.logger.error(`Token refresh failed for @${handle}`, { error: String(err) });\n const issue = await ctx.issues.create({\n companyId: config.company_id,\n title: `OAuth token refresh failed for @${handle}`,\n description: `Token refresh failed for @${handle} at ${new Date().toISOString()}.\\n\\nError: ${String(err)}\\n\\nManual re-auth may be required via setup-oauth tool.`,\n });\n await ctx.issues.update(issue.id, { status: \"todo\" as const }, config.company_id);\n }\n }\n}\n\nasync function handlePublishScheduled(ctx: PluginContext, _job: PluginJobContext): Promise<void> {\n const config = await getConfig(ctx);\n\n const now = new Date().toISOString();\n const entities = await ctx.entities.list({ entityType: ENTITY_TYPES.draft, limit: 100 });\n const due = entities.filter((e) => {\n const d = e.data as unknown as DraftData;\n return d.schedule_at && d.schedule_at <= now && (d.status === \"approved\" || d.status === \"draft\");\n });\n\n for (const entity of due) {\n const draft = entity.data as unknown as DraftData;\n\n // Resolve account from draft, fall back to default\n const resolved = resolveAccount(config, draft.account);\n if (!resolved.ok) {\n ctx.logger.error(`Scheduled draft ${entity.id}: ${resolved.error}`);\n continue;\n }\n const { handle, account } = resolved;\n\n const approval = await checkApproval(ctx, config, \"scheduled\", entity.id, account.approval_modes);\n if (!approval.allowed) {\n ctx.logger.info(`Scheduled draft ${entity.id} blocked: ${approval.reason}`);\n continue;\n }\n\n try {\n const token = await getValidAccessToken(ctx, config, handle);\n\n if (draft.format === \"thread\" && draft.thread_tweets) {\n await publishThread(ctx, token, handle, draft.thread_tweets, draft.metadata, config.company_id);\n } else {\n const result = await createTweet(ctx.http, token, {\n text: draft.text,\n reply_to: draft.reply_to_tweet_id,\n quote_tweet_id: draft.quote_tweet_id,\n });\n await updateRateLimits(ctx, handle, \"post_tweets\", result.rateLimit);\n\n await ctx.entities.upsert({\n entityType: ENTITY_TYPES.publishedPost,\n scopeKind: \"instance\",\n externalId: result.data.id,\n title: draft.text.slice(0, 60),\n data: {\n tweet_id: result.data.id,\n account: handle,\n text: result.data.text,\n published_at: new Date().toISOString(),\n draft_id: entity.id,\n format: draft.format,\n metadata: draft.metadata,\n } as unknown as Record<string, unknown>,\n });\n\n await ctx.events.emit(EVENT_NAMES.postPublished, config.company_id, {\n tweet_id: result.data.id,\n text: draft.text,\n format: draft.format,\n metadata: draft.metadata,\n });\n }\n\n // Mark draft as published\n draft.status = \"approved\";\n await ctx.entities.upsert({\n entityType: ENTITY_TYPES.draft,\n scopeKind: \"instance\",\n externalId: entity.externalId ?? undefined,\n title: entity.title ?? draft.text.slice(0, 60),\n data: draft as unknown as Record<string, unknown>,\n });\n\n ctx.logger.info(`Published scheduled draft ${entity.id}`);\n } catch (err) {\n ctx.logger.error(`Failed to publish scheduled draft ${entity.id}`, { error: String(err) });\n }\n }\n}\n\nasync function handleMetricsCapture(ctx: PluginContext, _job: PluginJobContext): Promise<void> {\n const config = await getConfig(ctx);\n const resolved = resolveAccount(config);\n if (!resolved.ok) { ctx.logger.error(resolved.error); return; }\n const { handle } = resolved;\n\n const lookbackMs = config.metrics_capture_lookback_days * 86400000;\n const cutoff = new Date(Date.now() - lookbackMs).toISOString();\n const entities = await ctx.entities.list({ entityType: ENTITY_TYPES.publishedPost, limit: 500 });\n const recent = entities.filter((e) => {\n const d = e.data as unknown as PublishedPostData;\n return d.published_at >= cutoff && d.format !== \"repost\";\n });\n\n if (recent.length === 0) return;\n\n const tweetIds = recent.map((e) => (e.data as unknown as PublishedPostData).tweet_id);\n const token = await getValidAccessToken(ctx, config, handle);\n\n const batchSize = 100;\n for (let i = 0; i < tweetIds.length; i += batchSize) {\n const batch = tweetIds.slice(i, i + batchSize);\n const url = `https://api.x.com/2/tweets?ids=${batch.join(\",\")}&tweet.fields=public_metrics`;\n const resp = await ctx.http.fetch(url, {\n headers: { Authorization: `Bearer ${token}` },\n });\n\n if (!resp.ok) {\n ctx.logger.error(\"Metrics capture batch failed\", { status: resp.status });\n continue;\n }\n\n const body = (await resp.json()) as { data?: Array<{ id: string; public_metrics: { like_count: number; retweet_count: number; reply_count: number; impression_count?: number } }> };\n if (!body.data) continue;\n\n for (const tweet of body.data) {\n const entity = recent.find((e) => (e.data as unknown as PublishedPostData).tweet_id === tweet.id);\n if (!entity) continue;\n\n const data = entity.data as unknown as PublishedPostData;\n const newMetrics = {\n likes: tweet.public_metrics.like_count,\n retweets: tweet.public_metrics.retweet_count,\n replies: tweet.public_metrics.reply_count,\n impressions: tweet.public_metrics.impression_count || 0,\n captured_at: new Date().toISOString(),\n };\n\n // Check milestones\n const totalEngagement = newMetrics.likes + newMetrics.retweets + newMetrics.replies;\n const prevTotal = data.metrics\n ? data.metrics.likes + data.metrics.retweets + data.metrics.replies\n : 0;\n\n for (const milestone of config.engagement_milestones) {\n if (totalEngagement >= milestone && prevTotal < milestone) {\n await ctx.events.emit(EVENT_NAMES.postEngagementMilestone, config.company_id, {\n tweet_id: tweet.id,\n milestone,\n current_metrics: newMetrics,\n });\n }\n }\n\n data.metrics = newMetrics;\n await ctx.entities.upsert({\n entityType: ENTITY_TYPES.publishedPost,\n scopeKind: \"instance\",\n externalId: entity.externalId ?? undefined,\n title: entity.title ?? data.text.slice(0, 60),\n data: data as unknown as Record<string, unknown>,\n });\n }\n }\n\n ctx.logger.info(`Metrics captured for ${recent.length} posts`);\n}\n\nasync function handleStaleDraftCleanup(ctx: PluginContext, _job: PluginJobContext): Promise<void> {\n const cutoff = new Date(Date.now() - 48 * 3600000).toISOString();\n const entities = await ctx.entities.list({ entityType: ENTITY_TYPES.draft, limit: 500 });\n let staleCount = 0;\n\n for (const entity of entities) {\n const data = entity.data as unknown as DraftData;\n if ((data.status === \"draft\" || data.status === \"in_review\") && entity.createdAt < cutoff) {\n data.status = \"stale\";\n await ctx.entities.upsert({\n entityType: ENTITY_TYPES.draft,\n scopeKind: \"instance\",\n externalId: entity.externalId ?? undefined,\n title: entity.title ?? data.text.slice(0, 60),\n data: data as unknown as Record<string, unknown>,\n });\n staleCount++;\n }\n }\n\n if (staleCount > 0) {\n ctx.logger.info(`Marked ${staleCount} drafts as stale`);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Plugin definition\n// ---------------------------------------------------------------------------\n\nlet pluginCtx: PluginContext | null = null;\n\nconst plugin = definePlugin({\n async setup(ctx) {\n pluginCtx = ctx;\n\n // Register job handlers\n ctx.jobs.register(JOB_KEYS.tokenRefresh, (job) => handleTokenRefresh(ctx, job));\n ctx.jobs.register(JOB_KEYS.publishScheduled, (job) => handlePublishScheduled(ctx, job));\n ctx.jobs.register(JOB_KEYS.metricsCapture, (job) => handleMetricsCapture(ctx, job));\n ctx.jobs.register(JOB_KEYS.staleDraftCleanup, (job) => handleStaleDraftCleanup(ctx, job));\n\n // Register agent tools\n const p = (params: unknown) => params as Record<string, unknown>;\n ctx.tools.register(\n TOOL_NAMES.setupOauth,\n { displayName: \"Setup OAuth\", description: \"Seed initial OAuth tokens\", parametersSchema: {} },\n (params) => handleSetupOauth(ctx, p(params)),\n );\n ctx.tools.register(\n TOOL_NAMES.draftPost,\n { displayName: \"Draft Post\", description: \"Create a draft post\", parametersSchema: {} },\n (params) => handleDraftPost(ctx, p(params)),\n );\n ctx.tools.register(\n TOOL_NAMES.draftThread,\n { displayName: \"Draft Thread\", description: \"Create a draft thread\", parametersSchema: {} },\n (params) => handleDraftThread(ctx, p(params)),\n );\n ctx.tools.register(\n TOOL_NAMES.updateDraft,\n { displayName: \"Update Draft\", description: \"Update an existing draft\", parametersSchema: {} },\n (params) => handleUpdateDraft(ctx, p(params)),\n );\n ctx.tools.register(\n TOOL_NAMES.publishPost,\n { displayName: \"Publish Post\", description: \"Publish a tweet to X\", parametersSchema: {} },\n (params) => handlePublishPost(ctx, p(params)),\n );\n ctx.tools.register(\n TOOL_NAMES.replyToTweet,\n { displayName: \"Reply to Tweet\", description: \"Post a reply to a tweet\", parametersSchema: {} },\n (params) => handleReplyToTweet(ctx, p(params)),\n );\n ctx.tools.register(\n TOOL_NAMES.quoteTweet,\n { displayName: \"Quote Tweet\", description: \"Post a quote tweet\", parametersSchema: {} },\n (params) => handleQuoteTweet(ctx, p(params)),\n );\n ctx.tools.register(\n TOOL_NAMES.repost,\n { displayName: \"Repost\", description: \"Repost a tweet\", parametersSchema: {} },\n (params) => handleRepost(ctx, p(params)),\n );\n ctx.tools.register(\n TOOL_NAMES.schedulePost,\n { displayName: \"Schedule Post\", description: \"Schedule a post for later\", parametersSchema: {} },\n (params) => handleSchedulePost(ctx, p(params)),\n );\n ctx.tools.register(\n TOOL_NAMES.publishThread,\n { displayName: \"Publish Thread\", description: \"Publish a multi-tweet thread\", parametersSchema: {} },\n (params) => handlePublishThread(ctx, p(params)),\n );\n ctx.tools.register(\n TOOL_NAMES.getDrafts,\n { displayName: \"Get Drafts\", description: \"Query drafts by status\", parametersSchema: {} },\n (params) => handleGetDrafts(ctx, p(params)),\n );\n ctx.tools.register(\n TOOL_NAMES.getSchedule,\n { displayName: \"Get Schedule\", description: \"Get upcoming scheduled posts\", parametersSchema: {} },\n (params) => handleGetSchedule(ctx, p(params)),\n );\n ctx.tools.register(\n TOOL_NAMES.getPostMetrics,\n { displayName: \"Get Post Metrics\", description: \"Get engagement metrics for a post\", parametersSchema: {} },\n (params) => handleGetPostMetrics(ctx, p(params)),\n );\n ctx.tools.register(\n TOOL_NAMES.getAccountStatus,\n { displayName: \"Get Account Status\", description: \"Account health and rate limits\", parametersSchema: {} },\n (params) => handleGetAccountStatus(ctx, p(params)),\n );\n\n // Register UI data handlers\n ctx.data.register(\"dashboard-summary\", async () => {\n const config = await getConfig(ctx);\n const accounts = config.accounts || {};\n const handles = Object.keys(accounts);\n const today = new Date().toISOString().split(\"T\")[0]!;\n const published = await ctx.entities.list({ entityType: ENTITY_TYPES.publishedPost, limit: 100 });\n const drafts = await ctx.entities.list({ entityType: ENTITY_TYPES.draft, limit: 100 });\n\n const todayPosts = published.filter((e) =>\n (e.data as unknown as PublishedPostData).published_at.startsWith(today),\n );\n\n const pendingDrafts = drafts.filter((e) => {\n const d = e.data as unknown as DraftData;\n return d.status === \"draft\" || d.status === \"in_review\" || d.status === \"approved\";\n });\n\n // Per-account token health summary\n const accountHealth: Record<string, string> = {};\n for (const handle of handles) {\n try {\n const tokens = await getTokens(ctx, handle);\n accountHealth[handle] = tokens.expires_at > Date.now() ? \"valid\" : \"expired\";\n } catch {\n accountHealth[handle] = \"not configured\";\n }\n }\n const allValid = Object.values(accountHealth).every((h) => h === \"valid\");\n const tokenHealth = handles.length === 0 ? \"no accounts\" : allValid ? \"valid\" : \"degraded\";\n\n const recentPosts = published\n .map((e) => e.data as unknown as PublishedPostData)\n .sort((a, b) => (a.published_at > b.published_at ? -1 : 1))\n .slice(0, 5);\n\n return {\n today_post_count: todayPosts.length,\n daily_limit: config.daily_post_limit,\n pending_drafts: pendingDrafts.length,\n token_health: tokenHealth,\n accounts: accountHealth,\n recent_posts: recentPosts,\n };\n });\n\n ctx.data.register(\"plugin-config\", async () => {\n const config = await getConfig(ctx);\n return config as unknown as Record<string, unknown>;\n });\n\n ctx.data.register(\"content-queue\", async () => {\n const allDrafts = await ctx.entities.list({ entityType: ENTITY_TYPES.draft, limit: 100 });\n\n const pending = allDrafts\n .map((e) => {\n const d = e.data as unknown as DraftData;\n return { id: e.id, text: d.text, format: d.format, status: d.status, schedule_at: d.schedule_at };\n })\n .filter((d) => (d.status === \"draft\" || d.status === \"in_review\" || d.status === \"approved\") && !d.schedule_at);\n\n const scheduled = allDrafts\n .map((e) => {\n const d = e.data as unknown as DraftData;\n return { id: e.id, text: d.text, format: d.format, status: d.status, schedule_at: d.schedule_at };\n })\n .filter((d): d is typeof d & { schedule_at: string } =>\n !!d.schedule_at && (d.status === \"draft\" || d.status === \"approved\" || d.status === \"in_review\"))\n .sort((a, b) => (a.schedule_at > b.schedule_at ? 1 : -1));\n\n return { drafts: pending, scheduled };\n });\n\n // Cross-plugin event subscriptions (logging only for v1)\n ctx.events.on(`plugin.${ENTITY_TYPES.draft}` as never, async () => {\n // placeholder \u2014 can't subscribe to x-intelligence events without the exact\n // event type string at compile time. Wire this up at deployment time.\n });\n\n ctx.logger.info(\"X Publishing plugin initialized\");\n },\n\n async onHealth() {\n if (!pluginCtx) return { status: \"error\" as const, message: \"Plugin not initialized\" };\n\n const config = await getConfig(pluginCtx);\n const accounts = config.accounts || {};\n const handles = Object.keys(accounts);\n\n if (handles.length === 0) {\n return { status: \"error\" as const, message: \"No accounts configured\" };\n }\n\n let status: \"ok\" | \"degraded\" | \"error\" = \"ok\";\n const issues: string[] = [];\n const accountDetails: Record<string, unknown> = {};\n\n for (const handle of handles) {\n const detail: Record<string, unknown> = { role: accounts[handle]!.role };\n try {\n const tokens = await getTokens(pluginCtx, handle);\n const tokenOk = tokens.expires_at > Date.now();\n const minutesLeft = Math.round((tokens.expires_at - Date.now()) / 60000);\n detail.token = tokenOk ? `valid (${minutesLeft}m remaining)` : \"expired\";\n if (!tokenOk) {\n if (status === \"ok\") status = \"degraded\";\n issues.push(`@${handle} token expired`);\n }\n } catch {\n status = \"error\";\n issues.push(`@${handle} no tokens`);\n detail.token = \"not configured\";\n }\n\n try {\n const raw = await pluginCtx.state.get(stateKey(accountStateKey(STATE_KEYS.rateLimits, handle)));\n if (raw) {\n const limits = raw as unknown as RateLimitState;\n detail.rate_limits = { remaining: limits.post_tweets?.remaining ?? \"unknown\", daily: limits.daily_posts ?? 0 };\n if (limits.post_tweets && limits.post_tweets.remaining === 0 && limits.post_tweets.reset_at > Date.now()) {\n if (status === \"ok\") status = \"degraded\";\n issues.push(`@${handle} rate limited`);\n }\n }\n } catch { /* no rate limit data yet */ }\n\n accountDetails[handle] = detail;\n }\n\n const message = issues.length > 0 ? issues.join(\"; \") : `All ${handles.length} account(s) operational`;\n return { status, message, details: { accounts: accountDetails } };\n },\n\n async onValidateConfig(config: Record<string, unknown>) {\n const warnings: string[] = [];\n const errors: string[] = [];\n\n const accounts = (config.accounts || {}) as Record<string, { x_handle?: string; x_user_id?: string }>;\n const handles = Object.keys(accounts);\n\n if (handles.length === 0) {\n errors.push(\"At least one account is required in accounts map\");\n }\n\n const defaultAcct = config.default_account as string | undefined;\n if (defaultAcct && handles.length > 0 && !accounts[defaultAcct]) {\n errors.push(`default_account \"${defaultAcct}\" is not in the accounts map. Available: ${handles.join(\", \")}`);\n }\n\n for (const handle of handles) {\n const acct = accounts[handle]!;\n if (!acct.x_handle) errors.push(`Account ${handle}: x_handle is required`);\n if (!acct.x_user_id) errors.push(`Account ${handle}: x_user_id is required`);\n }\n\n if (pluginCtx) {\n const clientIdRef = (config.oauth_client_id_ref as string) || DEFAULT_CONFIG.oauth_client_id_ref;\n const clientSecretRef = (config.oauth_client_secret_ref as string) || DEFAULT_CONFIG.oauth_client_secret_ref;\n\n try {\n await pluginCtx.secrets.resolve(clientIdRef);\n } catch {\n errors.push(\"Could not resolve oauth_client_id_ref secret\");\n }\n\n try {\n await pluginCtx.secrets.resolve(clientSecretRef);\n } catch {\n errors.push(\"Could not resolve oauth_client_secret_ref secret\");\n }\n\n for (const handle of handles) {\n try {\n await getTokens(pluginCtx, handle);\n } catch {\n warnings.push(`No OAuth tokens for @${handle} \u2014 run setup-oauth tool`);\n }\n }\n }\n\n return { ok: errors.length === 0, warnings, errors };\n },\n});\n\nexport default plugin;\nrunWorker(plugin, import.meta.url);\n"],
|
|
5
|
+
"mappings": ";AA4PM,SAAU,aAAa,YAA4B;AACvD,SAAO,OAAO,OAAO,EAAE,WAAU,CAAE;AACrC;;;AC1NA,OAAO,UAAU;AACjB,SAAS,uBAA4D;AACrE,SAAS,qBAAqB;;;ACcvB,IAAM,kBAAkB;AAwGxB,IAAM,sBAAsB;;EAEjC,aAAa;;EAEb,iBAAiB;;EAEjB,kBAAkB;;EAElB,gBAAgB;;EAEhB,gBAAgB;;AAcX,IAAM,yBAAyB;;EAEpC,oBAAoB;;EAEpB,mBAAmB;;EAEnB,cAAc;;EAEd,SAAS;;EAET,wBAAwB;;EAExB,SAAS;;AA6lBX,IAAI,UAAU;AAGd,IAAM,kBAAkB,OAAO,mBAAmB;AAS5C,SAAU,cACd,QACA,QACA,IAAc;AAEd,MAAI,WAAW,iBAAiB;AAC9B,cAAU;EACZ;AACA,SAAO;IACL,SAAS;IACT,IAAI,MAAM;IACV;IACA;;AAEJ;AAQM,SAAU,sBACd,IACA,QAAe;AAEf,SAAO;IACL,SAAS;IACT;IACA;;AAEJ;AAUM,SAAU,oBACd,IACA,MACA,SACA,MAAY;AAEZ,QAAM,WAAwC;IAC5C,SAAS;IACT;IACA,OAAO,SAAS,SACZ,EAAE,MAAM,SAAS,KAAI,IACrB,EAAE,MAAM,QAAO;;AAErB,SAAO;AACT;AAQM,SAAU,mBACd,QACA,QAAe;AAEf,SAAO;IACL,SAAS;IACT;IACA;;AAEJ;AAWM,SAAU,iBAAiB,OAAc;AAC7C,MAAI,OAAO,UAAU,YAAY,UAAU;AAAM,WAAO;AACxD,QAAM,MAAM;AACZ,SACE,IAAI,YAAY,mBAChB,OAAO,IAAI,WAAW,YACtB,QAAQ,OACR,IAAI,OAAO,UACX,IAAI,OAAO;AAEf;AAOM,SAAU,sBACd,OAAc;AAEd,MAAI,OAAO,UAAU,YAAY,UAAU;AAAM,WAAO;AACxD,QAAM,MAAM;AACZ,SACE,IAAI,YAAY,mBAChB,OAAO,IAAI,WAAW,YACtB,EAAE,QAAQ;AAEd;AAKM,SAAU,kBAAkB,OAAc;AAC9C,MAAI,OAAO,UAAU,YAAY,UAAU;AAAM,WAAO;AACxD,QAAM,MAAM;AACZ,SACE,IAAI,YAAY,mBAChB,QAAQ,QACP,YAAY,OAAO,WAAW;AAEnC;AAKM,SAAU,yBACd,UAAyB;AAEzB,SAAO,YAAY,YAAY,EAAE,WAAW,YAAY,SAAS,UAAU;AAC7E;AAKM,SAAU,uBACd,UAAyB;AAEzB,SAAO,WAAW,YAAY,SAAS,UAAU;AACnD;AAYO,IAAM,oBAAoB;AAS3B,SAAU,iBAAiB,SAAuB;AACtD,SAAO,KAAK,UAAU,OAAO,IAAI;AACnC;AAYM,SAAU,aAAa,MAAY;AACvC,QAAM,UAAU,KAAK,KAAI;AACzB,MAAI,QAAQ,WAAW,GAAG;AACxB,UAAM,IAAI,kBAAkB,eAAe;EAC7C;AAEA,MAAI;AACJ,MAAI;AACF,aAAS,KAAK,MAAM,OAAO;EAC7B,QAAQ;AACN,UAAM,IAAI,kBAAkB,iBAAiB,QAAQ,MAAM,GAAG,GAAG,CAAC,EAAE;EACtE;AAEA,MAAI,OAAO,WAAW,YAAY,WAAW,MAAM;AACjD,UAAM,IAAI,kBAAkB,+BAA+B;EAC7D;AAEA,QAAM,MAAM;AAEZ,MAAI,IAAI,YAAY,iBAAiB;AACnC,UAAM,IAAI,kBACR,iDAAiD,eAAe,UAAU,KAAK,UAAU,IAAI,OAAO,CAAC,GAAG;EAE5G;AAIA,SAAO;AACT;AASM,IAAO,oBAAP,cAAiC,MAAK;EACxB,OAAO;EACzB,YAAY,SAAe;AACzB,UAAM,OAAO;EACf;;AAQI,IAAO,mBAAP,cAAgC,MAAK;EACvB,OAAO;;EAEhB;;EAEA;EAET,YAAY,OAAmB;AAC7B,UAAM,MAAM,OAAO;AACnB,SAAK,OAAO,MAAM;AAClB,SAAK,OAAO,MAAM;EACpB;;;;ADp3BF,IAAM,yBAAyB;AAiCzB,SAAU,UACdA,SACA,WACA,SAA0B;AAE1B,MACE,SAAS,SAAS,QAClB,SAAS,UAAU,MACnB;AACA,WAAO,mBAAmB;MACxB,QAAAA;MACA,OAAO,QAAQ;MACf,QAAQ,QAAQ;KACjB;EACH;AACA,QAAM,QAAQ,QAAQ,KAAK,CAAC;AAC5B,MAAI,OAAO,UAAU;AAAU;AAC/B,QAAM,WAAW,KAAK,QAAQ,cAAc,SAAS,CAAC;AACtD,QAAM,YAAY,KAAK,QAAQ,KAAK;AACpC,MAAI,aAAa,WAAW;AAC1B,uBAAmB,EAAE,QAAAA,QAAM,CAAE;EAC/B;AACF;AAsBM,SAAU,mBAAmB,SAA6B;AAC9D,QAAM,EAAE,QAAAA,QAAM,IAAK;AACnB,QAAM,cAAc,QAAQ,SAAS,QAAQ;AAC7C,QAAM,eAAe,QAAQ,UAAU,QAAQ;AAC/C,QAAM,eAAe,QAAQ,gBAAgB;AAM7C,MAAI,UAAU;AACd,MAAI,cAAc;AAClB,MAAI,WAA6C;AACjD,MAAI,gBAAyC,CAAA;AAG7C,QAAM,gBAAqC,CAAA;AAC3C,QAAM,cAAc,oBAAI,IAAG;AAC3B,QAAM,wBAAwB,oBAAI,IAAG;AACrC,QAAM,eAAe,oBAAI,IAAG;AAC5B,QAAM,iBAAiB,oBAAI,IAAG;AAC9B,QAAM,eAAe,oBAAI,IAAG;AAM5B,QAAM,wBAAwB,oBAAI,IAAG;AAGrC,QAAM,kBAAkB,oBAAI,IAAG;AAI/B,MAAI,iBAAiB;AACrB,QAAM,kBAAkB,OAAO,mBAAmB;AAMlD,WAAS,YAAY,SAAgB;AACnC,QAAI,CAAC;AAAS;AACd,UAAM,aAAa,iBAAiB,OAAc;AAClD,iBAAa,MAAM,UAAU;EAC/B;AAKA,WAAS,SACP,QACA,QACA,WAAkB;AAElB,WAAO,IAAI,QAAmC,CAAC,SAAS,WAAU;AAChE,UAAI,CAAC,SAAS;AACZ,eAAO,IAAI,MAAM,gBAAgB,MAAM,yCAAoC,CAAC;AAC5E;MACF;AAEA,UAAI,kBAAkB,iBAAiB;AACrC,yBAAiB;MACnB;AACA,YAAM,KAAK;AACX,YAAM,UAAU,aAAa;AAC7B,UAAI,UAAU;AAEd,YAAM,SAAS,CAAI,IAAwB,UAAkB;AAC3D,YAAI;AAAS;AACb,kBAAU;AACV,qBAAa,KAAK;AAClB,wBAAgB,OAAO,EAAE;AACzB,WAAG,KAAK;MACV;AAEA,YAAM,QAAQ,WAAW,MAAK;AAC5B,eACE,QACA,IAAI,iBAAiB;UACnB,MAAM,uBAAuB;UAC7B,SAAS,0BAAqB,MAAM,qBAAqB,OAAO;SACjE,CAAC;MAEN,GAAG,OAAO;AAEV,sBAAgB,IAAI,IAAI;QACtB,SAAS,CAAC,aAA6B;AACrC,cAAI,yBAAyB,QAAQ,GAAG;AACtC,mBAAO,SAAS,SAAS,MAAmC;UAC9D,WAAW,uBAAuB,QAAQ,GAAG;AAC3C,mBAAO,QAAQ,IAAI,iBAAiB,SAAS,KAAK,CAAC;UACrD,OAAO;AACL,mBAAO,QAAQ,IAAI,MAAM,mCAAmC,MAAM,GAAG,CAAC;UACxE;QACF;QACA;OACD;AAED,UAAI;AACF,cAAM,UAAU,cAAc,QAAQ,QAAQ,EAAE;AAChD,oBAAY,OAAO;MACrB,SAAS,KAAK;AACZ,eAAO,QAAQ,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,GAAG,CAAC,CAAC;MACpE;IACF,CAAC;EACH;AAKA,WAAS,WAAW,QAAgB,QAAe;AACjD,QAAI;AACF,kBAAY,mBAAmB,QAAQ,MAAM,CAAC;IAChD,QAAQ;IAER;EACF;AAMA,WAAS,eAAY;AACnB,WAAO;MACL,IAAI,WAAQ;AACV,YAAI,CAAC;AAAU,gBAAM,IAAI,MAAM,+CAA+C;AAC9E,eAAO;MACT;MAEA,QAAQ;QACN,MAAM,MAAG;AACP,iBAAO,SAAS,cAAc,CAAA,CAA2B;QAC3D;;MAGF,QAAQ;QACN,GACE,MACA,YACA,SAA+C;AAE/C,cAAI;AACJ,cAAI,OAAO,eAAe,YAAY;AACpC,2BAAe,EAAE,MAAM,IAAI,WAAU;UACvC,OAAO;AACL,gBAAI,CAAC;AAAS,oBAAM,IAAI,MAAM,oCAAoC;AAClE,2BAAe,EAAE,MAAM,QAAQ,YAAY,IAAI,QAAO;UACxD;AACA,wBAAc,KAAK,YAAY;AAE/B,eAAK,SAAS,oBAAoB,EAAE,cAAc,MAAM,QAAQ,aAAa,UAAU,KAAI,CAAE,EAAE,MAAM,CAAC,QAAO;AAC3G,uBAAW,OAAO;cAChB,OAAO;cACP,SAAS,iCAAiC,IAAI,cAAc,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;aAC7G;UACH,CAAC;AACD,iBAAO,MAAK;AACV,kBAAM,MAAM,cAAc,QAAQ,YAAY;AAC9C,gBAAI,QAAQ;AAAI,4BAAc,OAAO,KAAK,CAAC;UAC7C;QACF;QAEA,MAAM,KAAK,MAAc,WAAmB,SAAgB;AAC1D,gBAAM,SAAS,eAAe,EAAE,MAAM,WAAW,QAAO,CAAE;QAC5D;;MAGF,MAAM;QACJ,SAAS,KAAa,IAA4C;AAChE,sBAAY,IAAI,KAAK,EAAE;QACzB;;MAGF,WAAW;QACT,SAAS,UAAoC;AAC3C,gCAAsB,IAAI,SAAS,IAAI,QAAQ;QACjD;;MAGF,MAAM;QACJ,MAAM,MAAM,KAAa,MAAkB;AACzC,gBAAM,iBAA0C,CAAA;AAChD,cAAI,MAAM;AACR,gBAAI,KAAK;AAAQ,6BAAe,SAAS,KAAK;AAC9C,gBAAI,KAAK,SAAS;AAEhB,kBAAI,KAAK,mBAAmB,SAAS;AACnC,sBAAM,MAA8B,CAAA;AACpC,qBAAK,QAAQ,QAAQ,CAAC,GAAG,MAAK;AAAG,sBAAI,CAAC,IAAI;gBAAG,CAAC;AAC9C,+BAAe,UAAU;cAC3B,WAAW,MAAM,QAAQ,KAAK,OAAO,GAAG;AACtC,sBAAM,MAA8B,CAAA;AACpC,2BAAW,CAAC,GAAG,CAAC,KAAK,KAAK;AAAS,sBAAI,CAAC,IAAI;AAC5C,+BAAe,UAAU;cAC3B,OAAO;AACL,+BAAe,UAAU,KAAK;cAChC;YACF;AACA,gBAAI,KAAK,SAAS,UAAa,KAAK,SAAS,MAAM;AACjD,6BAAe,OAAO,OAAO,KAAK,SAAS,WACvC,KAAK,OACL,OAAO,KAAK,IAAI;YACtB;UACF;AAEA,gBAAM,SAAS,MAAM,SAAS,cAAc;YAC1C;YACA,MAAM,OAAO,KAAK,cAAc,EAAE,SAAS,IAAI,iBAAiB;WACjE;AAGD,iBAAO,IAAI,SAAS,OAAO,MAAM;YAC/B,QAAQ,OAAO;YACf,YAAY,OAAO;YACnB,SAAS,OAAO;WACjB;QACH;;MAGF,SAAS;QACP,MAAM,QAAQ,WAAiB;AAC7B,iBAAO,SAAS,mBAAmB,EAAE,UAAS,CAAE;QAClD;;MAGF,UAAU;QACR,MAAM,IAAI,OAAK;AACb,gBAAM,SAAS,gBAAgB;YAC7B,WAAW,MAAM;YACjB,SAAS,MAAM;YACf,YAAY,MAAM;YAClB,UAAU,MAAM;YAChB,UAAU,MAAM;WACjB;QACH;;MAGF,OAAO;QACL,MAAM,IAAI,OAAe;AACvB,iBAAO,SAAS,aAAa;YAC3B,WAAW,MAAM;YACjB,SAAS,MAAM;YACf,WAAW,MAAM;YACjB,UAAU,MAAM;WACjB;QACH;QAEA,MAAM,IAAI,OAAiB,OAAc;AACvC,gBAAM,SAAS,aAAa;YAC1B,WAAW,MAAM;YACjB,SAAS,MAAM;YACf,WAAW,MAAM;YACjB,UAAU,MAAM;YAChB;WACD;QACH;QAEA,MAAM,OAAO,OAAe;AAC1B,gBAAM,SAAS,gBAAgB;YAC7B,WAAW,MAAM;YACjB,SAAS,MAAM;YACf,WAAW,MAAM;YACjB,UAAU,MAAM;WACjB;QACH;;MAGF,UAAU;QACR,MAAM,OAAO,OAAK;AAChB,iBAAO,SAAS,mBAAmB;YACjC,YAAY,MAAM;YAClB,WAAW,MAAM;YACjB,SAAS,MAAM;YACf,YAAY,MAAM;YAClB,OAAO,MAAM;YACb,QAAQ,MAAM;YACd,MAAM,MAAM;WACb;QACH;QAEA,MAAM,KAAK,OAAK;AACd,iBAAO,SAAS,iBAAiB;YAC/B,YAAY,MAAM;YAClB,WAAW,MAAM;YACjB,SAAS,MAAM;YACf,YAAY,MAAM;YAClB,OAAO,MAAM;YACb,QAAQ,MAAM;WACf;QACH;;MAGF,UAAU;QACR,MAAM,KAAK,OAAK;AACd,iBAAO,SAAS,iBAAiB;YAC/B,WAAW,MAAM;YACjB,OAAO,MAAM;YACb,QAAQ,MAAM;WACf;QACH;QAEA,MAAM,IAAI,WAAmB,WAAiB;AAC5C,iBAAO,SAAS,gBAAgB,EAAE,WAAW,UAAS,CAAE;QAC1D;QAEA,MAAM,eAAe,WAAmB,WAAiB;AACvD,iBAAO,SAAS,2BAA2B,EAAE,WAAW,UAAS,CAAE;QACrE;QAEA,MAAM,oBAAoB,WAAmB,WAAiB;AAC5D,iBAAO,SAAS,gCAAgC,EAAE,WAAW,UAAS,CAAE;QAC1E;QAEA,MAAM,qBAAqB,SAAiB,WAAiB;AAC3D,iBAAO,SAAS,iCAAiC,EAAE,SAAS,UAAS,CAAE;QACzE;;MAGF,WAAW;QACT,MAAM,KAAK,OAAK;AACd,iBAAO,SAAS,kBAAkB;YAChC,OAAO,OAAO;YACd,QAAQ,OAAO;WAChB;QACH;QAEA,MAAM,IAAI,WAAiB;AACzB,iBAAO,SAAS,iBAAiB,EAAE,UAAS,CAAE;QAChD;;MAGF,QAAQ;QACN,MAAM,KAAK,OAAK;AACd,iBAAO,SAAS,eAAe;YAC7B,WAAW,MAAM;YACjB,WAAW,MAAM;YACjB,iBAAiB,MAAM;YACvB,QAAQ,MAAM;YACd,OAAO,MAAM;YACb,QAAQ,MAAM;WACf;QACH;QAEA,MAAM,IAAI,SAAiB,WAAiB;AAC1C,iBAAO,SAAS,cAAc,EAAE,SAAS,UAAS,CAAE;QACtD;QAEA,MAAM,OAAO,OAAK;AAChB,iBAAO,SAAS,iBAAiB;YAC/B,WAAW,MAAM;YACjB,WAAW,MAAM;YACjB,QAAQ,MAAM;YACd,UAAU,MAAM;YAChB,OAAO,MAAM;YACb,aAAa,MAAM;YACnB,UAAU,MAAM;YAChB,iBAAiB,MAAM;WACxB;QACH;QAEA,MAAM,OAAO,SAAiB,OAAO,WAAiB;AACpD,iBAAO,SAAS,iBAAiB;YAC/B;YACA;YACA;WACD;QACH;QAEA,MAAM,aAAa,SAAiB,WAAiB;AACnD,iBAAO,SAAS,uBAAuB,EAAE,SAAS,UAAS,CAAE;QAC/D;QAEA,MAAM,cAAc,SAAiB,MAAc,WAAiB;AAClE,iBAAO,SAAS,wBAAwB,EAAE,SAAS,MAAM,UAAS,CAAE;QACtE;QAEA,WAAW;UACT,MAAM,KAAK,SAAiB,WAAiB;AAC3C,mBAAO,SAAS,yBAAyB,EAAE,SAAS,UAAS,CAAE;UACjE;UAEA,MAAM,IAAI,SAAiB,KAAa,WAAiB;AACvD,mBAAO,SAAS,wBAAwB,EAAE,SAAS,KAAK,UAAS,CAAE;UACrE;UAEA,MAAM,OAAO,OAAK;AAChB,mBAAO,SAAS,2BAA2B;cACzC,SAAS,MAAM;cACf,KAAK,MAAM;cACX,MAAM,MAAM;cACZ,WAAW,MAAM;cACjB,OAAO,MAAM;cACb,QAAQ,MAAM;cACd,eAAe,MAAM;aACtB;UACH;UAEA,MAAM,OAAO,SAAiB,KAAa,WAAiB;AAC1D,mBAAO,SAAS,2BAA2B,EAAE,SAAS,KAAK,UAAS,CAAE;UACxE;;;MAIJ,QAAQ;QACN,MAAM,KAAK,OAAK;AACd,iBAAO,SAAS,eAAe;YAC7B,WAAW,MAAM;YACjB,QAAQ,MAAM;YACd,OAAO,MAAM;YACb,QAAQ,MAAM;WACf;QACH;QAEA,MAAM,IAAI,SAAiB,WAAiB;AAC1C,iBAAO,SAAS,cAAc,EAAE,SAAS,UAAS,CAAE;QACtD;QAEA,MAAM,MAAM,SAAiB,WAAiB;AAC5C,iBAAO,SAAS,gBAAgB,EAAE,SAAS,UAAS,CAAE;QACxD;QAEA,MAAM,OAAO,SAAiB,WAAiB;AAC7C,iBAAO,SAAS,iBAAiB,EAAE,SAAS,UAAS,CAAE;QACzD;QAEA,MAAM,OAAO,SAAiB,WAAmB,MAAyC;AACxF,iBAAO,SAAS,iBAAiB,EAAE,SAAS,WAAW,QAAQ,KAAK,QAAQ,QAAQ,KAAK,OAAM,CAAE;QACnG;QAEA,UAAU;UACR,MAAM,OAAO,SAAiB,WAAmB,MAA4C;AAC3F,mBAAO,SAAS,0BAA0B;cACxC;cACA;cACA,SAAS,MAAM;cACf,QAAQ,MAAM;aACf;UACH;UAEA,MAAM,KAAK,SAAiB,WAAiB;AAC3C,mBAAO,SAAS,wBAAwB,EAAE,SAAS,UAAS,CAAE;UAChE;UAEA,MAAM,YAAY,WAAmB,WAAmB,MAIvD;AACC,gBAAI,KAAK,SAAS;AAChB,oCAAsB,IAAI,WAAW,KAAK,OAAO;YACnD;AACA,gBAAI;AACF,qBAAO,MAAM,SAAS,+BAA+B;gBACnD;gBACA;gBACA,QAAQ,KAAK;gBACb,QAAQ,KAAK;eACd;YACH,SAAS,KAAK;AACZ,oCAAsB,OAAO,SAAS;AACtC,oBAAM;YACR;UACF;UAEA,MAAM,MAAM,WAAmB,WAAiB;AAC9C,kCAAsB,OAAO,SAAS;AACtC,kBAAM,SAAS,yBAAyB,EAAE,WAAW,UAAS,CAAE;UAClE;;;MAIJ,OAAO;QACL,MAAM,KAAK,OAAK;AACd,iBAAO,SAAS,cAAc;YAC5B,WAAW,MAAM;YACjB,OAAO,MAAM;YACb,QAAQ,MAAM;YACd,OAAO,MAAM;YACb,QAAQ,MAAM;WACf;QACH;QAEA,MAAM,IAAI,QAAgB,WAAiB;AACzC,iBAAO,SAAS,aAAa,EAAE,QAAQ,UAAS,CAAE;QACpD;QAEA,MAAM,OAAO,OAAK;AAChB,iBAAO,SAAS,gBAAgB;YAC9B,WAAW,MAAM;YACjB,OAAO,MAAM;YACb,aAAa,MAAM;YACnB,OAAO,MAAM;YACb,QAAQ,MAAM;YACd,UAAU,MAAM;YAChB,cAAc,MAAM;WACrB;QACH;QAEA,MAAM,OAAO,QAAgB,OAAO,WAAiB;AACnD,iBAAO,SAAS,gBAAgB;YAC9B;YACA;YACA;WACD;QACH;;MAGF,MAAM;QACJ,SAAS,KAAa,SAA8D;AAClF,uBAAa,IAAI,KAAK,OAAO;QAC/B;;MAGF,SAAS;QACP,SAAS,KAAa,SAA8D;AAClF,yBAAe,IAAI,KAAK,OAAO;QACjC;;MAGF,SAAU,uBAAK;AAEb,cAAM,oBAAoB,oBAAI,IAAG;AACjC,eAAO;UACL,KAAK,SAAiB,WAAiB;AACrC,8BAAkB,IAAI,SAAS,SAAS;AACxC,uBAAW,gBAAgB,EAAE,SAAS,UAAS,CAAE;UACnD;UACA,KAAK,SAAiB,OAAc;AAClC,kBAAM,YAAY,kBAAkB,IAAI,OAAO,KAAK;AACpD,uBAAW,gBAAgB,EAAE,SAAS,WAAW,MAAK,CAAE;UAC1D;UACA,MAAM,SAAe;AACnB,kBAAM,YAAY,kBAAkB,IAAI,OAAO,KAAK;AACpD,8BAAkB,OAAO,OAAO;AAChC,uBAAW,iBAAiB,EAAE,SAAS,UAAS,CAAE;UACpD;;MAEJ,GAAE;MAEF,OAAO;QACL,SACE,MACA,aACA,IAAoE;AAEpE,uBAAa,IAAI,MAAM,EAAE,aAAa,GAAE,CAAE;QAC5C;;MAGF,SAAS;QACP,MAAM,MAAM,MAAc,OAAe,MAA6B;AACpE,gBAAM,SAAS,iBAAiB,EAAE,MAAM,OAAO,KAAI,CAAE;QACvD;;MAGF,QAAQ;QACN,KAAK,SAAiB,MAA8B;AAClD,qBAAW,OAAO,EAAE,OAAO,QAAQ,SAAS,KAAI,CAAE;QACpD;QACA,KAAK,SAAiB,MAA8B;AAClD,qBAAW,OAAO,EAAE,OAAO,QAAQ,SAAS,KAAI,CAAE;QACpD;QACA,MAAM,SAAiB,MAA8B;AACnD,qBAAW,OAAO,EAAE,OAAO,SAAS,SAAS,KAAI,CAAE;QACrD;QACA,MAAM,SAAiB,MAA8B;AACnD,qBAAW,OAAO,EAAE,OAAO,SAAS,SAAS,KAAI,CAAE;QACrD;;;EAGN;AAEA,QAAM,MAAM,aAAY;AAWxB,iBAAe,kBAAkB,SAAuB;AACtD,UAAM,EAAE,IAAI,QAAQ,OAAM,IAAK;AAE/B,QAAI;AACF,YAAM,SAAS,MAAM,eAAe,QAAQ,MAAM;AAClD,kBAAY,sBAAsB,IAAI,UAAU,IAAI,CAAC;IACvD,SAAS,KAAK;AACZ,YAAM,eAAe,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAIpE,YAAM,YACJ,OAAQ,KAAa,SAAS,WACzB,IAAY,OACb,uBAAuB;AAE7B,kBAAY,oBAAoB,IAAI,WAAW,YAAY,CAAC;IAC9D;EACF;AAKA,iBAAe,eAAe,QAAgB,QAAe;AAC3D,YAAQ,QAAQ;MACd,KAAK;AACH,eAAO,iBAAiB,MAA0B;MAEpD,KAAK;AACH,eAAO,aAAY;MAErB,KAAK;AACH,eAAO,eAAc;MAEvB,KAAK;AACH,eAAO,qBAAqB,MAA8B;MAE5D,KAAK;AACH,eAAO,oBAAoB,MAA6B;MAE1D,KAAK;AACH,eAAO,cAAc,MAAuB;MAE9C,KAAK;AACH,eAAO,aAAa,MAAsB;MAE5C,KAAK;AACH,eAAO,cAAc,MAA4B;MAEnD,KAAK;AACH,eAAO,cAAc,MAAuB;MAE9C,KAAK;AACH,eAAO,oBAAoB,MAA6B;MAE1D,KAAK;AACH,eAAO,kBAAkB,MAA2B;MAEtD;AACE,cAAM,OAAO,OACX,IAAI,MAAM,mBAAmB,MAAM,EAAE,GACrC,EAAE,MAAM,oBAAoB,iBAAgB,CAAE;IAEpD;EACF;AAMA,iBAAe,iBAAiB,QAAwB;AACtD,QAAI,aAAa;AACf,YAAM,IAAI,MAAM,4BAA4B;IAC9C;AAEA,eAAW,OAAO;AAClB,oBAAgB,OAAO;AAGvB,UAAMA,QAAO,WAAW,MAAM,GAAG;AAEjC,kBAAc;AAGd,UAAM,mBAA6B,CAAA;AACnC,QAAIA,QAAO,WAAW;AAAkB,uBAAiB,KAAK,gBAAgB;AAC9E,QAAIA,QAAO,WAAW;AAAiB,uBAAiB,KAAK,eAAe;AAC5E,QAAIA,QAAO,WAAW;AAAU,uBAAiB,KAAK,QAAQ;AAC9D,QAAIA,QAAO,WAAW;AAAY,uBAAiB,KAAK,UAAU;AAElE,WAAO,EAAE,IAAI,MAAM,iBAAgB;EACrC;AAEA,iBAAe,eAAY;AACzB,QAAIA,QAAO,WAAW,UAAU;AAC9B,aAAOA,QAAO,WAAW,SAAQ;IACnC;AAEA,WAAO,EAAE,QAAQ,KAAI;EACvB;AAEA,iBAAe,iBAAc;AAC3B,QAAIA,QAAO,WAAW,YAAY;AAChC,YAAMA,QAAO,WAAW,WAAU;IACpC;AAMA,iBAAa,MAAK;AAChB,cAAO;AACP,UAAI,CAAC,QAAQ,SAAS,CAAC,QAAQ,QAAQ;AACrC,gBAAQ,KAAK,CAAC;MAChB;IACF,CAAC;EACH;AAEA,iBAAe,qBACb,QAA4B;AAE5B,QAAI,CAACA,QAAO,WAAW,kBAAkB;AACvC,YAAM,OAAO,OACX,IAAI,MAAM,kDAAkD,GAC5D,EAAE,MAAM,uBAAuB,uBAAsB,CAAE;IAE3D;AACA,WAAOA,QAAO,WAAW,iBAAiB,OAAO,MAAM;EACzD;AAEA,iBAAe,oBAAoB,QAA2B;AAC5D,oBAAgB,OAAO;AAEvB,QAAIA,QAAO,WAAW,iBAAiB;AACrC,YAAMA,QAAO,WAAW,gBAAgB,OAAO,MAAM;IACvD;EACF;AAEA,iBAAe,cAAc,QAAqB;AAChD,UAAM,QAAQ,OAAO;AAErB,eAAW,gBAAgB,eAAe;AAExC,YAAM,aAAa,aAAa,SAAS,MAAM;AAC/C,YAAM,oBACJ,aAAa,SAAS,cACtB,MAAM,UAAU,WAAW,SAAS;AACtC,YAAM,oBACJ,aAAa,KAAK,SAAS,IAAI,KAC/B,MAAM,UAAU,WAAW,aAAa,KAAK,MAAM,GAAG,EAAE,CAAC;AAE3D,UAAI,CAAC,cAAc,CAAC,qBAAqB,CAAC;AAAmB;AAG7D,UAAI,aAAa,UAAU,CAAC,YAAY,aAAa,QAAQ,KAAK;AAAG;AAErE,UAAI;AACF,cAAM,aAAa,GAAG,KAAK;MAC7B,SAAS,KAAK;AAGZ,mBAAW,OAAO;UAChB,OAAO;UACP,SAAS,sBAAsB,aAAa,IAAI,aAC9C,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CACjD;UACA,MAAM,EAAE,WAAW,MAAM,WAAW,OAAO,eAAe,QAAQ,IAAI,QAAQ,OAAS;SACxF;MACH;IACF;EACF;AAEA,iBAAe,aAAa,QAAoB;AAC9C,UAAM,UAAU,YAAY,IAAI,OAAO,IAAI,MAAM;AACjD,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI,MAAM,kCAAkC,OAAO,IAAI,MAAM,GAAG;IACxE;AACA,UAAM,QAAQ,OAAO,GAAG;EAC1B;AAEA,iBAAe,cAAc,QAA0B;AACrD,QAAI,CAACA,QAAO,WAAW,WAAW;AAChC,YAAM,OAAO,OACX,IAAI,MAAM,iDAAiD,GAC3D,EAAE,MAAM,uBAAuB,uBAAsB,CAAE;IAE3D;AACA,UAAMA,QAAO,WAAW,UAAU,MAAM;EAC1C;AAEA,iBAAe,cAAc,QAAqB;AAChD,UAAM,UAAU,aAAa,IAAI,OAAO,GAAG;AAC3C,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI,MAAM,uCAAuC,OAAO,GAAG,GAAG;IACtE;AACA,WAAO,QACL,OAAO,sBAAsB,SACzB,OAAO,SACP,EAAE,GAAG,OAAO,QAAQ,mBAAmB,OAAO,kBAAiB,CAAE;EAEzE;AAEA,iBAAe,oBAAoB,QAA2B;AAC5D,UAAM,UAAU,eAAe,IAAI,OAAO,GAAG;AAC7C,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI,MAAM,yCAAyC,OAAO,GAAG,GAAG;IACxE;AACA,WAAO,QACL,OAAO,sBAAsB,SACzB,OAAO,SACP,EAAE,GAAG,OAAO,QAAQ,mBAAmB,OAAO,kBAAiB,CAAE;EAEzE;AAEA,iBAAe,kBAAkB,QAAyB;AACxD,UAAM,QAAQ,aAAa,IAAI,OAAO,QAAQ;AAC9C,QAAI,CAAC,OAAO;AACV,YAAM,IAAI,MAAM,mCAAmC,OAAO,QAAQ,GAAG;IACvE;AACA,WAAO,MAAM,GAAG,OAAO,YAAY,OAAO,UAAU;EACtD;AAMA,WAAS,YAAY,QAAqB,OAAkB;AAC1D,UAAM,UAAU,MAAM;AAEtB,QAAI,OAAO,cAAc,QAAW;AAClC,YAAM,YAAY,MAAM,aAAa,OAAO,SAAS,aAAa,EAAE;AACpE,UAAI,cAAc,OAAO;AAAW,eAAO;IAC7C;AAEA,QAAI,OAAO,cAAc,QAAW;AAClC,YAAM,YAAY,MAAM,eAAe,YACnC,MAAM,WACN,OAAO,SAAS,aAAa,EAAE;AACnC,UAAI,cAAc,OAAO;AAAW,eAAO;IAC7C;AAEA,QAAI,OAAO,YAAY,QAAW;AAChC,YAAM,UAAU,MAAM,eAAe,UACjC,MAAM,WACN,OAAO,SAAS,WAAW,EAAE;AACjC,UAAI,YAAY,OAAO;AAAS,eAAO;IACzC;AAEA,WAAO;EACT;AAMA,WAAS,mBAAmB,UAAyB;AACnD,UAAM,KAAK,SAAS;AACpB,QAAI,OAAO,QAAQ,OAAO;AAAW;AAErC,UAAM,UAAU,gBAAgB,IAAI,EAAE;AACtC,QAAI,CAAC;AAAS;AAEd,iBAAa,QAAQ,KAAK;AAC1B,oBAAgB,OAAO,EAAE;AACzB,YAAQ,QAAQ,QAAQ;EAC1B;AAMA,WAAS,WAAW,MAAY;AAC9B,QAAI,CAAC,KAAK,KAAI;AAAI;AAElB,QAAI;AACJ,QAAI;AACF,gBAAU,aAAa,IAAI;IAC7B,SAAS,KAAK;AACZ,UAAI,eAAe,mBAAmB;AAEpC,oBACE,oBACE,MACA,oBAAoB,aACpB,gBAAgB,IAAI,OAAO,EAAE,CAC9B;MAEL;AACA;IACF;AAEA,QAAI,kBAAkB,OAAO,GAAG;AAE9B,yBAAmB,OAAO;IAC5B,WAAW,iBAAiB,OAAO,GAAG;AAEpC,wBAAkB,OAAyB,EAAE,MAAM,CAAC,QAAO;AAEzD,cAAM,eAAe,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AACpE,cAAM,YAAa,KAAa,QAAQ,uBAAuB;AAC/D,YAAI;AACF,sBACE,oBACG,QAA2B,IAC5B,OAAO,cAAc,WAAW,YAAY,uBAAuB,cACnE,YAAY,CACb;QAEL,QAAQ;QAER;MACF,CAAC;IACH,WAAW,sBAAsB,OAAO,GAAG;AAEzC,YAAM,QAAQ;AACd,UAAI,MAAM,WAAW,2BAA2B,MAAM,QAAQ;AAC5D,cAAM,QAAQ,MAAM;AACpB,cAAM,KAAK,sBAAsB,IAAI,MAAM,SAAS;AACpD,YAAI;AAAI,aAAG,KAAK;MAClB,WAAW,MAAM,WAAW,aAAa,MAAM,QAAQ;AAErD,sBAAc,MAAM,MAAuB,EAAE,MAAM,CAAC,QAAO;AACzD,qBAAW,OAAO;YAChB,OAAO;YACP,SAAS,wCAAwC,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;WAClG;QACH,CAAC;MACH;IACF;EACF;AAMA,WAAS,UAAO;AACd,cAAU;AAGV,QAAI,UAAU;AACZ,eAAS,MAAK;AACd,iBAAW;IACb;AAGA,eAAW,CAAC,IAAI,OAAO,KAAK,iBAAiB;AAC3C,mBAAa,QAAQ,KAAK;AAC1B,cAAQ,QACN,oBACE,IACA,uBAAuB,oBACvB,kCAAkC,CAChB;IAExB;AACA,oBAAgB,MAAK;AACrB,0BAAsB,MAAK;EAC7B;AAMA,MAAI,WAAqC,gBAAgB;IACvD,OAAO;IACP,WAAW;GACZ;AAED,WAAS,GAAG,QAAQ,UAAU;AAG9B,WAAS,GAAG,SAAS,MAAK;AACxB,QAAI,SAAS;AACX,cAAO;AACP,UAAI,CAAC,QAAQ,SAAS,CAAC,QAAQ,QAAQ;AACrC,gBAAQ,KAAK,CAAC;MAChB;IACF;EACF,CAAC;AAKD,MAAI,CAAC,QAAQ,SAAS,CAAC,QAAQ,QAAQ;AACrC,YAAQ,GAAG,qBAAqB,CAAC,QAAO;AACtC,iBAAW,OAAO;QAChB,OAAO;QACP,SAAS,uBAAuB,IAAI,OAAO;QAC3C,MAAM,EAAE,OAAO,IAAI,MAAK;OACzB;AAED,iBAAW,MAAM,QAAQ,KAAK,CAAC,GAAG,GAAG;IACvC,CAAC;AAED,YAAQ,GAAG,sBAAsB,CAAC,WAAU;AAC1C,YAAM,UAAU,kBAAkB,QAAQ,OAAO,UAAU,OAAO,MAAM;AACxE,YAAM,QAAQ,kBAAkB,QAAQ,OAAO,QAAQ;AACvD,iBAAW,OAAO;QAChB,OAAO;QACP,SAAS,wBAAwB,OAAO;QACxC,MAAM,EAAE,MAAK;OACd;IACH,CAAC;EACH;AAMA,SAAO;IACL,IAAI,UAAO;AACT,aAAO;IACT;IAEA,OAAI;AACF,cAAO;IACT;;AAEJ;;;AErtCO,IAAM,aAAa;AAAA,EACxB,WAAW;AAAA,EACX,aAAa;AAAA,EACb,aAAa;AAAA,EACb,cAAc;AAAA,EACd,YAAY;AAAA,EACZ,QAAQ;AAAA,EACR,cAAc;AAAA,EACd,eAAe;AAAA,EACf,aAAa;AAAA,EACb,WAAW;AAAA,EACX,aAAa;AAAA,EACb,gBAAgB;AAAA,EAChB,kBAAkB;AAAA,EAClB,YAAY;AACd;AAEO,IAAM,WAAW;AAAA,EACtB,cAAc;AAAA,EACd,kBAAkB;AAAA,EAClB,gBAAgB;AAAA,EAChB,mBAAmB;AACrB;AAEO,IAAM,eAAe;AAAA,EAC1B,OAAO;AAAA,EACP,eAAe;AACjB;AAEO,IAAM,cAAc;AAAA,EACzB,eAAe;AAAA,EACf,cAAc;AAAA,EACd,kBAAkB;AAAA,EAClB,yBAAyB;AAAA,EACzB,iBAAiB;AACnB;AAEO,IAAM,aAAa;AAAA,EACxB,aAAa;AAAA,EACb,YAAY;AACd;AAgBO,IAAM,yBAAyB;AAAA,EACpC,OAAO;AAAA,EACP,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,WAAW;AACb;AAEO,IAAM,iBAAiB;AAAA,EAC5B,YAAY;AAAA,EACZ,qBAAqB;AAAA,EACrB,yBAAyB;AAAA,EACzB,iBAAiB;AAAA,EACjB,UAAU,CAAC;AAAA,EACX,kBAAkB;AAAA,EAClB,uBAAuB,CAAC,IAAI,KAAK,KAAK,GAAI;AAAA,EAC1C,+BAA+B;AAAA,EAC/B,cAAc,CAAC;AACjB;AAGO,SAAS,gBAAgB,MAAc,QAAwB;AACpE,SAAO,GAAG,IAAI,IAAI,MAAM;AAC1B;;;AC9EA,IAAM,oBAAoB,IAAI,KAAK;AAEnC,SAAS,SAAS,KAAa;AAC7B,SAAO,EAAE,WAAW,YAAqB,UAAU,IAAI;AACzD;AAEA,eAAsB,UAAU,KAAoB,QAAqC;AACvF,QAAM,MAAM,MAAM,IAAI,MAAM,IAAI,SAAS,gBAAgB,WAAW,aAAa,MAAM,CAAC,CAAC;AACzF,MAAI,CAAC,IAAK,OAAM,IAAI,MAAM,iCAAiC,MAAM,EAAE;AACnE,SAAO;AACT;AAEA,eAAsB,UAAU,KAAoB,QAAgB,QAAmC;AACrG,QAAM,IAAI,MAAM;AAAA,IACd,SAAS,gBAAgB,WAAW,aAAa,MAAM,CAAC;AAAA,IACxD;AAAA,EACF;AACF;AAEA,eAAsB,cAAc,KAAoBC,SAA0B,QAAqC;AACrH,QAAM,UAAU,MAAM,UAAU,KAAK,MAAM;AAC3C,QAAM,WAAW,MAAM,IAAI,QAAQ,QAAQA,QAAO,mBAAmB;AACrE,QAAM,eAAe,MAAM,IAAI,QAAQ,QAAQA,QAAO,uBAAuB;AAE7E,QAAM,OAAO,MAAM,IAAI,KAAK,MAAM,oCAAoC;AAAA,IACpE,QAAQ;AAAA,IACR,SAAS;AAAA,MACP,gBAAgB;AAAA,MAChB,eAAe,SAAS,KAAK,GAAG,QAAQ,IAAI,YAAY,EAAE,CAAC;AAAA,IAC7D;AAAA,IACA,MAAM,IAAI,gBAAgB;AAAA,MACxB,YAAY;AAAA,MACZ,eAAe,QAAQ;AAAA,IACzB,CAAC,EAAE,SAAS;AAAA,EACd,CAAC;AAED,MAAI,CAAC,KAAK,IAAI;AACZ,UAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,UAAM,IAAI,MAAM,6BAA6B,MAAM,UAAU,KAAK,MAAM,WAAM,IAAI,EAAE;AAAA,EACtF;AAEA,QAAM,OAAQ,MAAM,KAAK,KAAK;AAO9B,QAAM,YAAwB;AAAA,IAC5B,cAAc,KAAK;AAAA,IACnB,eAAe,KAAK;AAAA,IACpB,YAAY,KAAK,IAAI,IAAI,KAAK,aAAa;AAAA,EAC7C;AAEA,QAAM,UAAU,KAAK,QAAQ,SAAS;AACtC,SAAO;AACT;AAEA,eAAsB,oBAAoB,KAAoBA,SAA0B,QAAiC;AACvH,QAAM,SAAS,MAAM,UAAU,KAAK,MAAM;AAE1C,MAAI,OAAO,aAAa,KAAK,IAAI,IAAI,mBAAmB;AACtD,UAAM,YAAY,MAAM,cAAc,KAAKA,SAAQ,MAAM;AACzD,WAAO,UAAU;AAAA,EACnB;AAEA,SAAO,OAAO;AAChB;;;ACpEA,SAAS,sBAAsB,SAAoC;AACjE,QAAM,YAAY,SAAS,QAAQ,IAAI,wBAAwB,KAAK,MAAM,EAAE;AAC5E,QAAM,aAAa,SAAS,QAAQ,IAAI,oBAAoB,KAAK,KAAK,EAAE;AACxE,SAAO;AAAA,IACL;AAAA,IACA,UAAU,aAAa;AAAA;AAAA,EACzB;AACF;AAEA,eAAe,UAAa,IAAsB,aAAa,GAAe;AAC5E,WAAS,UAAU,GAAG,WAAW,YAAY,WAAW;AACtD,QAAI;AACF,aAAO,MAAM,GAAG;AAAA,IAClB,SAAS,KAAc;AACrB,YAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,UAAI,UAAU,cAAc,QAAQ,SAAS,KAAK,GAAG;AACnD,cAAM,YAAY,KAAK,IAAI,GAAG,UAAU,CAAC,IAAI;AAC7C,cAAM,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,SAAS,CAAC;AACjD;AAAA,MACF;AACA,YAAM;AAAA,IACR;AAAA,EACF;AACA,QAAM,IAAI,MAAM,aAAa;AAC/B;AAIA,eAAsB,YACpB,MACA,OACA,QAC8E;AAC9E,SAAO,UAAU,YAAY;AAC3B,UAAM,OAAgC,EAAE,MAAM,OAAO,KAAK;AAE1D,QAAI,OAAO,UAAU;AACnB,WAAK,QAAQ,EAAE,sBAAsB,OAAO,SAAS;AAAA,IACvD;AACA,QAAI,OAAO,gBAAgB;AACzB,WAAK,iBAAiB,OAAO;AAAA,IAC/B;AACA,QAAI,OAAO,aAAa,OAAO,UAAU,SAAS,GAAG;AACnD,WAAK,QAAQ,EAAE,WAAW,OAAO,UAAU;AAAA,IAC7C;AAEA,UAAM,OAAO,MAAM,KAAK,MAAM,8BAA8B;AAAA,MAC1D,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,eAAe,UAAU,KAAK;AAAA,QAC9B,gBAAgB;AAAA,MAClB;AAAA,MACA,MAAM,KAAK,UAAU,IAAI;AAAA,IAC3B,CAAC;AAED,QAAI,KAAK,WAAW,KAAK;AACvB,YAAM,IAAI,MAAM,kBAAkB;AAAA,IACpC;AAEA,QAAI,KAAK,WAAW,KAAK;AACvB,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,YAAM,IAAI,MAAM,6BAA6B,KAAK,MAAM,WAAM,IAAI,EAAE;AAAA,IACtE;AAEA,UAAM,OAAQ,MAAM,KAAK,KAAK;AAC9B,WAAO;AAAA,MACL,MAAM,KAAK;AAAA,MACX,WAAW,sBAAsB,KAAK,OAAO;AAAA,IAC/C;AAAA,EACF,CAAC;AACH;AA8BA,eAAsB,OACpB,MACA,OACA,QACA,SACwE;AACxE,SAAO,UAAU,YAAY;AAC3B,UAAM,OAAO,MAAM,KAAK,MAAM,6BAA6B,MAAM,aAAa;AAAA,MAC5E,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,eAAe,UAAU,KAAK;AAAA,QAC9B,gBAAgB;AAAA,MAClB;AAAA,MACA,MAAM,KAAK,UAAU,EAAE,UAAU,QAAQ,CAAC;AAAA,IAC5C,CAAC;AAED,QAAI,KAAK,WAAW,KAAK;AACvB,YAAM,IAAI,MAAM,kBAAkB;AAAA,IACpC;AAEA,QAAI,KAAK,WAAW,KAAK;AACvB,YAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,YAAM,IAAI,MAAM,uBAAuB,KAAK,MAAM,WAAM,IAAI,EAAE;AAAA,IAChE;AAEA,UAAM,OAAQ,MAAM,KAAK,KAAK;AAC9B,WAAO;AAAA,MACL,MAAM,KAAK;AAAA,MACX,WAAW,sBAAsB,KAAK,OAAO;AAAA,IAC/C;AAAA,EACF,CAAC;AACH;;;AClIA,SAASC,UAAS,KAAa;AAC7B,SAAO,EAAE,WAAW,YAAqB,UAAU,IAAI;AACzD;AAEA,IAAM,gBAAgC;AAAA,EACpC,aAAa,EAAE,WAAW,IAAI,UAAU,EAAE;AAAA,EAC1C,eAAe,EAAE,WAAW,IAAI,UAAU,EAAE;AAAA,EAC5C,UAAU,EAAE,WAAW,IAAI,UAAU,EAAE;AAAA,EACvC,aAAa;AAAA,EACb,gBAAgB;AAClB;AAEA,eAAe,kBAAkB,KAAoB,QAAyC;AAC5F,QAAM,MAAM,MAAM,IAAI,MAAM,IAAIA,UAAS,gBAAgB,WAAW,YAAY,MAAM,CAAC,CAAC;AACxF,MAAI,CAAC,IAAK,QAAO,EAAE,GAAG,cAAc;AACpC,QAAM,QAAQ;AAEd,MAAI,MAAM,kBAAkB,KAAK,IAAI,IAAI,MAAM,gBAAgB;AAC7D,UAAM,cAAc;AACpB,UAAM,iBAAiB,kBAAkB;AAAA,EAC3C;AAEA,SAAO;AACT;AAEA,SAAS,oBAA4B;AACnC,QAAM,MAAM,oBAAI,KAAK;AACrB,QAAM,WAAW,IAAI,KAAK,IAAI,YAAY,GAAG,IAAI,SAAS,GAAG,IAAI,QAAQ,IAAI,CAAC;AAC9E,SAAO,SAAS,QAAQ;AAC1B;AAEA,eAAsB,iBACpB,KACA,QACA,UACA,SACe;AACf,QAAM,QAAQ,MAAM,kBAAkB,KAAK,MAAM;AAEjD,QAAM,QAAQ,IAAI;AAAA,IAChB,WAAW,QAAQ;AAAA,IACnB,UAAU,QAAQ;AAAA,EACpB;AAEA,MAAI,aAAa,eAAe;AAC9B,UAAM;AACN,QAAI,CAAC,MAAM,gBAAgB;AACzB,YAAM,iBAAiB,kBAAkB;AAAA,IAC3C;AAAA,EACF;AAEA,QAAM,IAAI,MAAM;AAAA,IACdA,UAAS,gBAAgB,WAAW,YAAY,MAAM,CAAC;AAAA,IACvD;AAAA,EACF;AACF;;;AChDA,eAAsB,cACpB,KACAC,SACA,aACA,SACA,eACyB;AACzB,QAAM,QAAQ,iBAAiB;AAC/B,QAAM,OAAO,MAAM,WAAW;AAE9B,MAAI,SAAS,QAAQ;AACnB,WAAO,EAAE,SAAS,KAAK;AAAA,EACzB;AAEA,MAAI,SAAS,YAAY;AACvB,QAAI,OAAO,KAAK,yBAAyB,WAAW,cAAc;AAClE,WAAO,EAAE,SAAS,KAAK;AAAA,EACzB;AAGA,MAAI,CAAC,SAAS;AACZ,UAAM,QAAQ,MAAM,IAAI,OAAO,OAAO;AAAA,MACpC,WAAWA,QAAO;AAAA,MAClB,OAAO,yBAAyB,WAAW;AAAA,MAC3C,aAAa,iBAAiB,WAAW;AAAA;AAAA;AAAA,IAC3C,CAAC;AACD,UAAM,IAAI,OAAO,OAAO,MAAM,IAAI,EAAE,QAAQ,OAAgB,GAAGA,QAAO,UAAU;AAEhF,UAAM,IAAI,OAAO,KAAK,YAAY,kBAAkBA,QAAO,YAAY;AAAA,MACrE,cAAc;AAAA,MACd,QAAQ;AAAA,IACV,CAAC;AAED,WAAO,EAAE,SAAS,OAAO,QAAQ,yBAAyB,WAAW,8CAA8C;AAAA,EACrH;AAGA,QAAM,YAAY,MAAM,IAAI,SAAS,KAAK,EAAE,YAAY,aAAa,OAAO,OAAO,IAAI,CAAC;AACxF,QAAM,SAAS,UAAU,KAAK,CAAC,MAAM,EAAE,OAAO,OAAO;AACrD,MAAI,CAAC,QAAQ;AACX,WAAO,EAAE,SAAS,OAAO,QAAQ,SAAS,OAAO,cAAc;AAAA,EACjE;AAEA,QAAM,QAAQ,OAAO;AACrB,MAAI,MAAM,WAAW,YAAY;AAC/B,WAAO,EAAE,SAAS,KAAK;AAAA,EACzB;AAGA,MAAI,MAAM,WAAW,aAAa;AAChC,UAAM,SAAS;AACf,UAAM,QAAQ,MAAM,IAAI,OAAO,OAAO;AAAA,MACpC,WAAWA,QAAO;AAAA,MAClB,OAAO,iBAAiB,MAAM,KAAK,MAAM,GAAG,EAAE,CAAC;AAAA,MAC/C,aAAa,aAAa,OAAO;AAAA,UAAa,MAAM,MAAM;AAAA;AAAA;AAAA,EAAc,MAAM,IAAI,GAAG,MAAM,gBAAgB,kBAAkB,MAAM,cAAc,KAAK,SAAS,IAAI,EAAE;AAAA,IACvK,CAAC;AACD,UAAM,IAAI,OAAO,OAAO,MAAM,IAAI,EAAE,QAAQ,OAAgB,GAAGA,QAAO,UAAU;AAEhF,UAAM,kBAAkB,MAAM;AAC9B,UAAM,IAAI,SAAS,OAAO;AAAA,MACxB,YAAY,aAAa;AAAA,MACzB,WAAW;AAAA,MACX,YAAY,OAAO,cAAc;AAAA,MACjC,OAAO,OAAO,SAAS,MAAM,KAAK,MAAM,GAAG,EAAE;AAAA,MAC7C,MAAM;AAAA,IACR,CAAC;AAED,UAAM,IAAI,OAAO,KAAK,YAAY,kBAAkBA,QAAO,YAAY;AAAA,MACrE,UAAU;AAAA,MACV,cAAc;AAAA,MACd,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAEA,SAAO,EAAE,SAAS,OAAO,QAAQ,SAAS,OAAO,OAAO,MAAM,MAAM,yCAAyC;AAC/G;;;AChFA,IAAM,cAAc;AAOpB,eAAsB,cACpB,KACA,OACA,QACA,QACA,UACA,WACuB;AACvB,QAAM,WAAqB,CAAC;AAC5B,MAAI;AAEJ,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,UAAM,OAAO,OAAO,CAAC;AACrB,QAAI,SAAS;AAEb,aAAS,UAAU,GAAG,UAAU,aAAa,WAAW;AACtD,UAAI;AACF,cAAM,SAAS,MAAM,YAAY,IAAI,MAAM,OAAO;AAAA,UAChD;AAAA,UACA,UAAU;AAAA,QACZ,CAAC;AACD,cAAM,iBAAiB,KAAK,QAAQ,eAAe,OAAO,SAAS;AAEnE,iBAAS,KAAK,OAAO,KAAK,EAAE;AAC5B,kBAAU,OAAO,KAAK;AAEtB,cAAM,YAA+B;AAAA,UACnC,UAAU,OAAO,KAAK;AAAA,UACtB,SAAS;AAAA,UACT,MAAM,OAAO,KAAK;AAAA,UAClB,eAAc,oBAAI,KAAK,GAAE,YAAY;AAAA,UACrC,QAAQ;AAAA,UACR,kBAAkB,SAAS,MAAM;AAAA,UACjC;AAAA,QACF;AAEA,cAAM,IAAI,SAAS,OAAO;AAAA,UACxB,YAAY,aAAa;AAAA,UACzB,WAAW;AAAA,UACX,YAAY,OAAO,KAAK;AAAA,UACxB,OAAO,UAAU,IAAI,CAAC,IAAI,OAAO,MAAM,KAAK,KAAK,MAAM,GAAG,EAAE,CAAC;AAAA,UAC7D,MAAM;AAAA,QACR,CAAC;AAED,iBAAS;AACT;AAAA,MACF,SAAS,KAAK;AACZ,YAAI,OAAO,MAAM,gBAAgB,IAAI,CAAC,IAAI,OAAO,MAAM,YAAY,UAAU,CAAC,WAAW,EAAE,OAAO,OAAO,GAAG,EAAE,CAAC;AAC/G,YAAI,UAAU,cAAc,GAAG;AAC7B,gBAAM,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,KAAK,IAAI,GAAG,UAAU,CAAC,IAAI,GAAI,CAAC;AAAA,QACzE;AAAA,MACF;AAAA,IACF;AAEA,QAAI,CAAC,QAAQ;AACX,YAAM,QAAQ,MAAM,IAAI,OAAO,OAAO;AAAA,QACpC;AAAA,QACA,OAAO,kCAAkC,IAAI,CAAC,IAAI,OAAO,MAAM;AAAA,QAC/D,aAAa;AAAA;AAAA,uBAA2D,SAAS,KAAK,IAAI,CAAC;AAAA;AAAA,qBAA0B,IAAI;AAAA;AAAA,oBAAyB,OAAO,SAAS,CAAC;AAAA,MACrK,CAAC;AACD,YAAM,IAAI,OAAO,OAAO,MAAM,IAAI,EAAE,QAAQ,OAAgB,GAAG,SAAS;AAExE,aAAO,EAAE,UAAU,SAAS,KAAK;AAAA,IACnC;AAAA,EACF;AAEA,SAAO,EAAE,UAAU,SAAS,MAAM;AACpC;;;AC7CA,SAASC,UAAS,KAAa;AAC7B,SAAO,EAAE,WAAW,YAAqB,UAAU,IAAI;AACzD;AAEA,eAAe,UAAU,KAA+C;AACtE,QAAM,MAAM,MAAM,IAAI,OAAO,IAAI;AACjC,SAAO,EAAE,GAAG,gBAAgB,GAAG,IAAI;AACrC;AAGA,SAAS,eACPC,SACA,QACqF;AACrF,QAAM,WAAWA,QAAO,YAAY,CAAC;AACrC,QAAM,UAAU,OAAO,KAAK,QAAQ;AAEpC,MAAI,QAAQ,WAAW,GAAG;AACxB,WAAO,EAAE,IAAI,OAAO,OAAO,0BAA0B;AAAA,EACvD;AAEA,QAAM,SAAS,UAAUA,QAAO,mBAAmB,QAAQ,CAAC;AAC5D,QAAM,UAAU,SAAS,MAAM;AAC/B,MAAI,CAAC,SAAS;AACZ,WAAO,EAAE,IAAI,OAAO,OAAO,YAAY,MAAM,oCAAoC,QAAQ,KAAK,IAAI,CAAC,GAAG;AAAA,EACxG;AAEA,SAAO,EAAE,IAAI,MAAM,QAAQ,QAAQ,QAAQ;AAC7C;AAaA,SAAS,eAAkB,UAA0B,IAA+D;AAClH,QAAM,QAAQ,SAAS,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE;AAC9C,MAAI,CAAC,MAAO,QAAO;AACnB,SAAO,EAAE,IAAI,MAAM,IAAI,MAAM,MAAM,MAAsB,KAAK,MAAM;AACtE;AAMA,eAAe,iBAAiB,KAAoB,QAAsD;AACxG,QAAM,SAAS,OAAO;AACtB,MAAI,CAAC,OAAQ,QAAO,EAAE,OAAO,4DAA4D;AAEzF,QAAMA,UAAS,MAAM,UAAU,GAAG;AAClC,QAAM,WAAW,eAAeA,SAAQ,MAAM;AAC9C,MAAI,CAAC,SAAS,GAAI,QAAO,EAAE,OAAO,SAAS,MAAM;AAEjD,QAAM,cAAc,OAAO;AAC3B,QAAM,eAAe,OAAO;AAC5B,QAAM,YAAa,OAAO,cAAyB;AAEnD,QAAM,aAAyB;AAAA,IAC7B,cAAc;AAAA,IACd,eAAe;AAAA,IACf,YAAY,KAAK,IAAI,IAAI,YAAY;AAAA,EACvC;AACA,QAAM,UAAU,KAAK,QAAQ,UAAU;AAEvC,SAAO,EAAE,SAAS,4BAA4B,MAAM,gBAAgB,IAAI,KAAK,WAAW,UAAU,EAAE,YAAY,CAAC,IAAI;AACvH;AAEA,eAAe,gBAAgB,KAAoB,QAAsD;AACvG,QAAM,OAAO,OAAO;AACpB,MAAI,KAAK,SAAS,KAAK;AACrB,WAAO,EAAE,OAAO,sCAAsC,KAAK,MAAM,KAAK;AAAA,EACxE;AAEA,QAAMA,UAAS,MAAM,UAAU,GAAG;AAClC,QAAM,SAAU,OAAO,UAAqB;AAC5C,QAAM,WAAY,OAAO,YAAsC,CAAC;AAEhE,QAAM,QAAmB;AAAA,IACvB;AAAA,IACA;AAAA,IACA,SAAU,OAAO,WAAkCA,QAAO,mBAAmB;AAAA,IAC7E,mBAAmB,OAAO;AAAA,IAC1B,gBAAgB,OAAO;AAAA,IACvB,aAAa,OAAO;AAAA,IACpB,QAAQ;AAAA,IACR;AAAA,EACF;AAEA,QAAM,SAAS,MAAM,IAAI,SAAS,OAAO;AAAA,IACvC,YAAY,aAAa;AAAA,IACzB,WAAW;AAAA,IACX,OAAO,KAAK,MAAM,GAAG,EAAE;AAAA,IACvB,MAAM;AAAA,EACR,CAAC;AAED,QAAM,IAAI,OAAO,KAAK,YAAY,cAAcA,QAAO,YAAY;AAAA,IACjE,UAAU,OAAO;AAAA,IACjB;AAAA,IACA;AAAA,EACF,CAAC;AAED,SAAO,EAAE,SAAS,KAAK,UAAU,EAAE,UAAU,OAAO,IAAI,QAAQ,SAAS,OAAO,CAAC,EAAE;AACrF;AAEA,eAAe,kBAAkB,KAAoB,QAAsD;AACzG,QAAM,eAAe,OAAO;AAC5B,MAAI,CAAC,gBAAgB,aAAa,SAAS,GAAG;AAC5C,WAAO,EAAE,OAAO,sCAAsC;AAAA,EACxD;AAEA,WAAS,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;AAC5C,QAAI,aAAa,CAAC,EAAG,SAAS,KAAK;AACjC,aAAO,EAAE,OAAO,SAAS,IAAI,CAAC,4BAA4B,aAAa,CAAC,EAAG,MAAM,KAAK;AAAA,IACxF;AAAA,EACF;AAEA,QAAMA,UAAS,MAAM,UAAU,GAAG;AAClC,QAAM,WAAY,OAAO,YAAsC,CAAC;AAChE,QAAM,QAAmB;AAAA,IACvB,MAAM,aAAa,CAAC;AAAA,IACpB,QAAQ;AAAA,IACR,SAAU,OAAO,WAAkCA,QAAO,mBAAmB;AAAA,IAC7E,eAAe;AAAA,IACf,aAAa,OAAO;AAAA,IACpB,QAAQ;AAAA,IACR;AAAA,EACF;AAEA,QAAM,SAAS,MAAM,IAAI,SAAS,OAAO;AAAA,IACvC,YAAY,aAAa;AAAA,IACzB,WAAW;AAAA,IACX,OAAO,WAAW,aAAa,CAAC,EAAG,MAAM,GAAG,EAAE,CAAC;AAAA,IAC/C,MAAM;AAAA,EACR,CAAC;AAED,QAAM,IAAI,OAAO,KAAK,YAAY,cAAcA,QAAO,YAAY;AAAA,IACjE,UAAU,OAAO;AAAA,IACjB,QAAQ;AAAA,IACR;AAAA,EACF,CAAC;AAED,SAAO,EAAE,SAAS,KAAK,UAAU,EAAE,UAAU,OAAO,IAAI,QAAQ,SAAS,QAAQ,UAAU,aAAa,aAAa,OAAO,CAAC,EAAE;AACjI;AAEA,eAAe,kBAAkB,KAAoB,QAAsD;AACzG,QAAM,UAAU,OAAO;AACvB,QAAM,WAAW,MAAM,IAAI,SAAS,KAAK,EAAE,YAAY,aAAa,OAAO,OAAO,IAAI,CAAC;AACvF,QAAM,QAAQ,eAA0B,UAAU,OAAO;AACzD,MAAI,CAAC,MAAO,QAAO,EAAE,OAAO,SAAS,OAAO,cAAc;AAE1D,QAAM,OAAO,MAAM;AACnB,MAAI,OAAO,SAAS,OAAW,MAAK,OAAO,OAAO;AAClD,MAAI,OAAO,kBAAkB,OAAW,MAAK,gBAAgB,OAAO;AACpE,MAAI,OAAO,gBAAgB,OAAW,MAAK,cAAc,OAAO;AAChE,MAAI,OAAO,aAAa,OAAW,MAAK,WAAW,EAAE,GAAG,KAAK,UAAU,GAAI,OAAO,SAAmC;AACrH,OAAK,SAAS;AAEd,QAAM,IAAI,SAAS,OAAO;AAAA,IACxB,YAAY,aAAa;AAAA,IACzB,WAAW;AAAA,IACX,YAAY,MAAM,IAAI,cAAc;AAAA,IACpC,OAAO,KAAK,KAAK,MAAM,GAAG,EAAE;AAAA,IAC5B;AAAA,EACF,CAAC;AAED,SAAO,EAAE,SAAS,KAAK,UAAU,EAAE,UAAU,SAAS,QAAQ,SAAS,SAAS,KAAK,CAAC,EAAE;AAC1F;AAEA,eAAe,kBAAkB,KAAoB,QAAsD;AACzG,QAAMA,UAAS,MAAM,UAAU,GAAG;AAClC,QAAM,WAAW,eAAeA,SAAQ,OAAO,OAA6B;AAC5E,MAAI,CAAC,SAAS,GAAI,QAAO,EAAE,OAAO,SAAS,MAAM;AACjD,QAAM,EAAE,QAAQ,QAAQ,IAAI;AAE5B,MAAI,OAAO,OAAO;AAClB,MAAI,WAAY,OAAO,YAA8C,CAAC;AACtE,QAAM,UAAU,OAAO;AAEvB,MAAI,SAAS;AACX,UAAM,WAAW,MAAM,IAAI,SAAS,KAAK,EAAE,YAAY,aAAa,OAAO,OAAO,IAAI,CAAC;AACvF,UAAM,QAAQ,eAA0B,UAAU,OAAO;AACzD,QAAI,CAAC,MAAO,QAAO,EAAE,OAAO,SAAS,OAAO,cAAc;AAC1D,WAAO,MAAM,KAAK;AAClB,eAAW,EAAE,GAAG,MAAM,KAAK,UAAU,GAAG,SAAS;AAAA,EACnD;AAEA,MAAI,CAAC,KAAM,QAAO,EAAE,OAAO,oCAAoC;AAE/D,QAAM,WAAW,MAAM,cAAc,KAAKA,SAAQ,SAAS,SAAS,QAAQ,cAAc;AAC1F,MAAI,CAAC,SAAS,QAAS,QAAO,EAAE,OAAO,YAAY,SAAS,MAAM,GAAG;AAErE,QAAM,QAAQ,MAAM,oBAAoB,KAAKA,SAAQ,MAAM;AAC3D,QAAM,SAAS,MAAM,YAAY,IAAI,MAAM,OAAO,EAAE,KAAK,CAAC;AAC1D,QAAM,iBAAiB,KAAK,QAAQ,eAAe,OAAO,SAAS;AAEnE,QAAM,YAA+B;AAAA,IACnC,UAAU,OAAO,KAAK;AAAA,IACtB,SAAS;AAAA,IACT,MAAM,OAAO,KAAK;AAAA,IAClB,eAAc,oBAAI,KAAK,GAAE,YAAY;AAAA,IACrC,UAAU;AAAA,IACV,QAAQ;AAAA,IACR;AAAA,EACF;AAEA,QAAM,IAAI,SAAS,OAAO;AAAA,IACxB,YAAY,aAAa;AAAA,IACzB,WAAW;AAAA,IACX,YAAY,OAAO,KAAK;AAAA,IACxB,OAAO,KAAK,MAAM,GAAG,EAAE;AAAA,IACvB,MAAM;AAAA,EACR,CAAC;AAED,QAAM,IAAI,OAAO,KAAK,YAAY,eAAeA,QAAO,YAAY;AAAA,IAClE,UAAU,OAAO,KAAK;AAAA,IAAI;AAAA,IAAM,QAAQ;AAAA,IAAU;AAAA,EACpD,CAAC;AAED,SAAO,EAAE,SAAS,KAAK,UAAU,EAAE,UAAU,OAAO,KAAK,IAAI,MAAM,OAAO,KAAK,MAAM,QAAQ,YAAY,CAAC,EAAE;AAC9G;AAEA,eAAe,mBAAmB,KAAoB,QAAsD;AAC1G,QAAMA,UAAS,MAAM,UAAU,GAAG;AAClC,QAAM,WAAW,eAAeA,SAAQ,OAAO,OAA6B;AAC5E,MAAI,CAAC,SAAS,GAAI,QAAO,EAAE,OAAO,SAAS,MAAM;AACjD,QAAM,EAAE,QAAQ,QAAQ,IAAI;AAE5B,QAAM,UAAU,OAAO;AACvB,QAAM,OAAO,OAAO;AACpB,QAAM,WAAY,OAAO,YAA8C,CAAC;AAExE,QAAM,WAAW,MAAM,cAAc,KAAKA,SAAQ,WAAW,OAAO,UAAgC,QAAQ,cAAc;AAC1H,MAAI,CAAC,SAAS,QAAS,QAAO,EAAE,OAAO,YAAY,SAAS,MAAM,GAAG;AAErE,QAAM,QAAQ,MAAM,oBAAoB,KAAKA,SAAQ,MAAM;AAC3D,QAAM,SAAS,MAAM,YAAY,IAAI,MAAM,OAAO,EAAE,MAAM,UAAU,QAAQ,CAAC;AAC7E,QAAM,iBAAiB,KAAK,QAAQ,eAAe,OAAO,SAAS;AAEnE,QAAM,YAA+B;AAAA,IACnC,UAAU,OAAO,KAAK;AAAA,IACtB,SAAS;AAAA,IACT,MAAM,OAAO,KAAK;AAAA,IAClB,eAAc,oBAAI,KAAK,GAAE,YAAY;AAAA,IACrC,UAAU,OAAO;AAAA,IACjB,QAAQ;AAAA,IACR,UAAU,EAAE,GAAG,UAAU,iBAAiB,QAAQ;AAAA,EACpD;AAEA,QAAM,IAAI,SAAS,OAAO;AAAA,IACxB,YAAY,aAAa;AAAA,IACzB,WAAW;AAAA,IACX,YAAY,OAAO,KAAK;AAAA,IACxB,OAAO,UAAU,KAAK,MAAM,GAAG,EAAE,CAAC;AAAA,IAClC,MAAM;AAAA,EACR,CAAC;AAED,QAAM,IAAI,OAAO,KAAK,YAAY,eAAeA,QAAO,YAAY;AAAA,IAClE,UAAU,OAAO,KAAK;AAAA,IAAI;AAAA,IAAM,QAAQ;AAAA,IAAS,UAAU,UAAU;AAAA,EACvE,CAAC;AAED,SAAO,EAAE,SAAS,KAAK,UAAU,EAAE,UAAU,OAAO,KAAK,IAAI,MAAM,OAAO,KAAK,MAAM,QAAQ,aAAa,UAAU,QAAQ,CAAC,EAAE;AACjI;AAEA,eAAe,iBAAiB,KAAoB,QAAsD;AACxG,QAAMA,UAAS,MAAM,UAAU,GAAG;AAClC,QAAM,WAAW,eAAeA,SAAQ,OAAO,OAA6B;AAC5E,MAAI,CAAC,SAAS,GAAI,QAAO,EAAE,OAAO,SAAS,MAAM;AACjD,QAAM,EAAE,QAAQ,QAAQ,IAAI;AAE5B,QAAM,UAAU,OAAO;AACvB,QAAM,OAAO,OAAO;AACpB,QAAM,WAAY,OAAO,YAA8C,CAAC;AAExE,QAAM,WAAW,MAAM,cAAc,KAAKA,SAAQ,UAAU,OAAO,UAAgC,QAAQ,cAAc;AACzH,MAAI,CAAC,SAAS,QAAS,QAAO,EAAE,OAAO,YAAY,SAAS,MAAM,GAAG;AAErE,QAAM,QAAQ,MAAM,oBAAoB,KAAKA,SAAQ,MAAM;AAC3D,QAAM,SAAS,MAAM,YAAY,IAAI,MAAM,OAAO,EAAE,MAAM,gBAAgB,QAAQ,CAAC;AACnF,QAAM,iBAAiB,KAAK,QAAQ,eAAe,OAAO,SAAS;AAEnE,QAAM,YAA+B;AAAA,IACnC,UAAU,OAAO,KAAK;AAAA,IACtB,SAAS;AAAA,IACT,MAAM,OAAO,KAAK;AAAA,IAClB,eAAc,oBAAI,KAAK,GAAE,YAAY;AAAA,IACrC,UAAU,OAAO;AAAA,IACjB,QAAQ;AAAA,IACR,UAAU,EAAE,GAAG,UAAU,iBAAiB,QAAQ;AAAA,EACpD;AAEA,QAAM,IAAI,SAAS,OAAO;AAAA,IACxB,YAAY,aAAa;AAAA,IACzB,WAAW;AAAA,IACX,YAAY,OAAO,KAAK;AAAA,IACxB,OAAO,UAAU,KAAK,MAAM,GAAG,EAAE,CAAC;AAAA,IAClC,MAAM;AAAA,EACR,CAAC;AAED,QAAM,IAAI,OAAO,KAAK,YAAY,eAAeA,QAAO,YAAY;AAAA,IAClE,UAAU,OAAO,KAAK;AAAA,IAAI;AAAA,IAAM,QAAQ;AAAA,IAAS,UAAU,UAAU;AAAA,EACvE,CAAC;AAED,SAAO,EAAE,SAAS,KAAK,UAAU,EAAE,UAAU,OAAO,KAAK,IAAI,MAAM,OAAO,KAAK,MAAM,QAAQ,aAAa,QAAQ,QAAQ,CAAC,EAAE;AAC/H;AAEA,eAAe,aAAa,KAAoB,QAAsD;AACpG,QAAMA,UAAS,MAAM,UAAU,GAAG;AAClC,QAAM,WAAW,eAAeA,SAAQ,OAAO,OAA6B;AAC5E,MAAI,CAAC,SAAS,GAAI,QAAO,EAAE,OAAO,SAAS,MAAM;AACjD,QAAM,EAAE,QAAQ,QAAQ,IAAI;AAE5B,QAAM,UAAU,OAAO;AAEvB,QAAM,WAAW,MAAM,cAAc,KAAKA,SAAQ,WAAW,OAAO,UAAgC,QAAQ,cAAc;AAC1H,MAAI,CAAC,SAAS,QAAS,QAAO,EAAE,OAAO,YAAY,SAAS,MAAM,GAAG;AAErE,QAAM,QAAQ,MAAM,oBAAoB,KAAKA,SAAQ,MAAM;AAC3D,QAAM,SAAS,MAAM,OAAU,IAAI,MAAM,OAAO,QAAQ,WAAW,OAAO;AAC1E,QAAM,iBAAiB,KAAK,QAAQ,YAAY,OAAO,SAAS;AAEhE,QAAM,YAA+B;AAAA,IACnC,UAAU;AAAA,IACV,SAAS;AAAA,IACT,MAAM;AAAA,IACN,eAAc,oBAAI,KAAK,GAAE,YAAY;AAAA,IACrC,UAAU,OAAO;AAAA,IACjB,QAAQ;AAAA,IACR,UAAU,EAAE,iBAAiB,QAAQ;AAAA,EACvC;AAEA,QAAM,IAAI,SAAS,OAAO;AAAA,IACxB,YAAY,aAAa;AAAA,IACzB,WAAW;AAAA,IACX,YAAY,UAAU,OAAO;AAAA,IAC7B,OAAO,WAAW,OAAO;AAAA,IACzB,MAAM;AAAA,EACR,CAAC;AAED,QAAM,IAAI,OAAO,KAAK,YAAY,eAAeA,QAAO,YAAY;AAAA,IAClE,UAAU;AAAA,IAAS,MAAM;AAAA,IAAI,QAAQ;AAAA,IAAU,UAAU,UAAU;AAAA,EACrE,CAAC;AAED,SAAO,EAAE,SAAS,KAAK,UAAU,EAAE,UAAU,SAAS,QAAQ,WAAW,CAAC,EAAE;AAC9E;AAEA,eAAe,mBAAmB,KAAoB,QAAsD;AAC1G,QAAM,aAAa,OAAO;AAC1B,QAAM,UAAU,OAAO;AACvB,QAAM,OAAO,OAAO;AACpB,QAAM,WAAY,OAAO,YAAsC,CAAC;AAEhE,MAAI,SAAS;AACX,UAAM,WAAW,MAAM,IAAI,SAAS,KAAK,EAAE,YAAY,aAAa,OAAO,OAAO,IAAI,CAAC;AACvF,UAAM,QAAQ,eAA0B,UAAU,OAAO;AACzD,QAAI,CAAC,MAAO,QAAO,EAAE,OAAO,SAAS,OAAO,cAAc;AAC1D,UAAM,KAAK,cAAc;AACzB,UAAM,IAAI,SAAS,OAAO;AAAA,MACxB,YAAY,aAAa;AAAA,MACzB,WAAW;AAAA,MACX,YAAY,MAAM,IAAI,cAAc;AAAA,MACpC,OAAO,MAAM,KAAK,KAAK,MAAM,GAAG,EAAE;AAAA,MAClC,MAAM,MAAM;AAAA,IACd,CAAC;AACD,WAAO,EAAE,SAAS,KAAK,UAAU,EAAE,UAAU,SAAS,aAAa,YAAY,QAAQ,YAAY,CAAC,EAAE;AAAA,EACxG;AAEA,MAAI,CAAC,KAAM,QAAO,EAAE,OAAO,4BAA4B;AAEvD,QAAM,QAAmB;AAAA,IACvB;AAAA,IACA,QAAQ;AAAA,IACR,SAAU,OAAO,WAAkC,OAAO,mBAAmB;AAAA,IAC7E,aAAa;AAAA,IACb,QAAQ;AAAA,IACR;AAAA,EACF;AAEA,QAAM,SAAS,MAAM,IAAI,SAAS,OAAO;AAAA,IACvC,YAAY,aAAa;AAAA,IACzB,WAAW;AAAA,IACX,OAAO,KAAK,MAAM,GAAG,EAAE;AAAA,IACvB,MAAM;AAAA,EACR,CAAC;AAED,SAAO,EAAE,SAAS,KAAK,UAAU,EAAE,UAAU,OAAO,IAAI,aAAa,YAAY,QAAQ,YAAY,CAAC,EAAE;AAC1G;AAEA,eAAe,oBAAoB,KAAoB,QAAsD;AAC3G,QAAMA,UAAS,MAAM,UAAU,GAAG;AAClC,QAAM,WAAW,eAAeA,SAAQ,OAAO,OAA6B;AAC5E,MAAI,CAAC,SAAS,GAAI,QAAO,EAAE,OAAO,SAAS,MAAM;AACjD,QAAM,EAAE,QAAQ,QAAQ,IAAI;AAE5B,MAAI,eAAe,OAAO;AAC1B,MAAI,WAAY,OAAO,YAA8C,CAAC;AACtE,QAAM,UAAU,OAAO;AAEvB,MAAI,SAAS;AACX,UAAM,WAAW,MAAM,IAAI,SAAS,KAAK,EAAE,YAAY,aAAa,OAAO,OAAO,IAAI,CAAC;AACvF,UAAM,QAAQ,eAA0B,UAAU,OAAO;AACzD,QAAI,CAAC,MAAO,QAAO,EAAE,OAAO,SAAS,OAAO,cAAc;AAC1D,mBAAe,MAAM,KAAK;AAC1B,eAAW,EAAE,GAAG,MAAM,KAAK,UAAU,GAAG,SAAS;AAAA,EACnD;AAEA,MAAI,CAAC,gBAAgB,aAAa,SAAS,GAAG;AAC5C,WAAO,EAAE,OAAO,sCAAsC;AAAA,EACxD;AAEA,QAAM,WAAW,MAAM,cAAc,KAAKA,SAAQ,SAAS,SAAS,QAAQ,cAAc;AAC1F,MAAI,CAAC,SAAS,QAAS,QAAO,EAAE,OAAO,YAAY,SAAS,MAAM,GAAG;AAErE,QAAM,QAAQ,MAAM,oBAAoB,KAAKA,SAAQ,MAAM;AAC3D,QAAM,SAAS,MAAM,cAAc,KAAK,OAAO,QAAQ,cAAc,UAAUA,QAAO,UAAU;AAEhG,QAAM,IAAI,OAAO,KAAK,YAAY,iBAAiBA,QAAO,YAAY;AAAA,IACpE,WAAW,OAAO;AAAA,IAClB,eAAe,aAAa;AAAA,IAC5B,SAAS,OAAO;AAAA,EAClB,CAAC;AAED,aAAW,WAAW,OAAO,UAAU;AACrC,UAAM,IAAI,OAAO,KAAK,YAAY,eAAeA,QAAO,YAAY;AAAA,MAClE,UAAU;AAAA,MAAS,MAAM;AAAA,MAAI,QAAQ;AAAA,MAAU;AAAA,IACjD,CAAC;AAAA,EACH;AAEA,SAAO,EAAE,SAAS,KAAK,UAAU;AAAA,IAC/B,WAAW,OAAO;AAAA,IAClB,eAAe,aAAa;AAAA,IAC5B,SAAS,OAAO;AAAA,IAChB,QAAQ,OAAO,UAAU,YAAY;AAAA,EACvC,CAAC,EAAE;AACL;AAEA,eAAe,gBAAgB,KAAoB,QAAsD;AACvG,QAAM,eAAe,OAAO;AAC5B,QAAM,QAAS,OAAO,SAAoB;AAE1C,QAAM,WAAW,MAAM,IAAI,SAAS,KAAK,EAAE,YAAY,aAAa,OAAO,OAAO,IAAI,CAAC;AACvF,MAAI,SAAS,SAAS,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,GAAI,EAAE,KAA8B,EAAE;AAEpF,MAAI,cAAc;AAChB,aAAS,OAAO,OAAO,CAAC,MAAM,EAAE,WAAW,YAAY;AAAA,EACzD;AAEA,SAAO,EAAE,SAAS,KAAK,UAAU,OAAO,MAAM,GAAG,KAAK,CAAC,EAAE;AAC3D;AAEA,eAAe,kBAAkB,KAAoB,QAAsD;AACzG,QAAM,QAAS,OAAO,SAAoB;AAC1C,QAAM,WAAW,MAAM,IAAI,SAAS,KAAK,EAAE,YAAY,aAAa,OAAO,OAAO,IAAI,CAAC;AACvF,QAAM,YAAY,SACf,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,GAAI,EAAE,KAA8B,EAAE,EAC9D,OAAO,CAAC,MAAM,EAAE,gBAAgB,EAAE,WAAW,WAAW,EAAE,WAAW,WAAW,EAChF,KAAK,CAAC,GAAG,MAAO,EAAE,cAAe,EAAE,cAAe,IAAI,EAAG;AAE5D,SAAO,EAAE,SAAS,KAAK,UAAU,UAAU,MAAM,GAAG,KAAK,CAAC,EAAE;AAC9D;AAEA,eAAe,qBAAqB,KAAoB,QAAsD;AAC5G,QAAM,UAAU,OAAO;AACvB,QAAM,WAAW,MAAM,IAAI,SAAS,KAAK,EAAE,YAAY,aAAa,eAAe,OAAO,IAAI,CAAC;AAC/F,QAAM,OAAO,SAAS,KAAK,CAAC,MAAO,EAAE,KAAsC,aAAa,OAAO;AAE/F,MAAI,CAAC,KAAM,QAAO,EAAE,OAAO,qCAAqC,OAAO,IAAI;AAE3E,QAAM,OAAO,KAAK;AAClB,SAAO,EAAE,SAAS,KAAK,UAAU;AAAA,IAC/B,UAAU,KAAK;AAAA,IACf,MAAM,KAAK;AAAA,IACX,cAAc,KAAK;AAAA,IACnB,QAAQ,KAAK;AAAA,IACb,UAAU,KAAK;AAAA,IACf,SAAS,KAAK,WAAW;AAAA,EAC3B,CAAC,EAAE;AACL;AAEA,eAAe,uBAAuB,KAAoB,QAAsD;AAC9G,QAAMA,UAAS,MAAM,UAAU,GAAG;AAClC,QAAM,WAAWA,QAAO,YAAY,CAAC;AACrC,QAAM,UAAU,OAAO,UAAU,CAAC,OAAO,OAAiB,IAAI,OAAO,KAAK,QAAQ;AAElF,QAAM,SAAQ,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC;AACnD,QAAM,WAAW,MAAM,IAAI,SAAS,KAAK,EAAE,YAAY,aAAa,eAAe,OAAO,IAAI,CAAC;AAE/F,QAAM,WAAW,CAAC;AAClB,aAAW,UAAU,SAAS;AAC5B,QAAI,cAAc;AAClB,QAAI;AACF,YAAM,SAAS,MAAM,UAAU,KAAK,MAAM;AAC1C,UAAI,OAAO,aAAa,KAAK,IAAI,GAAG;AAClC,cAAM,cAAc,KAAK,OAAO,OAAO,aAAa,KAAK,IAAI,KAAK,GAAK;AACvE,sBAAc,UAAU,WAAW;AAAA,MACrC,OAAO;AACL,sBAAc;AAAA,MAChB;AAAA,IACF,QAAQ;AACN,oBAAc;AAAA,IAChB;AAEA,QAAI,aAAoC;AACxC,QAAI;AACF,YAAM,MAAM,MAAM,IAAI,MAAM,IAAID,UAAS,gBAAgB,WAAW,YAAY,MAAM,CAAC,CAAC;AACxF,UAAI,IAAK,cAAa;AAAA,IACxB,QAAQ;AAAA,IAA+B;AAEvC,UAAM,aAAa,SAAS,OAAO,CAAC,MAAM;AACxC,YAAM,OAAO,EAAE;AACf,aAAO,KAAK,aAAa,WAAW,KAAK,MAAM,CAAC,KAAK,WAAW,KAAK,YAAY;AAAA,IACnF,CAAC,EAAE;AAEH,aAAS,KAAK;AAAA,MACZ,UAAU;AAAA,MACV,MAAM,SAAS,MAAM,GAAG,QAAQ;AAAA,MAChC,cAAc;AAAA,MACd,aAAa,EAAE,OAAO,YAAY,OAAOC,QAAO,iBAAiB;AAAA,MACjE,aAAa;AAAA,IACf,CAAC;AAAA,EACH;AAEA,SAAO,EAAE,SAAS,KAAK,UAAU,QAAQ,WAAW,IAAI,SAAS,CAAC,IAAI,QAAQ,EAAE;AAClF;AAMA,eAAe,mBAAmB,KAAoB,MAAuC;AAC3F,QAAMA,UAAS,MAAM,UAAU,GAAG;AAClC,QAAM,UAAU,OAAO,KAAKA,QAAO,YAAY,CAAC,CAAC;AAEjD,aAAW,UAAU,SAAS;AAC5B,QAAI;AACF,YAAM,cAAc,KAAKA,SAAQ,MAAM;AACvC,UAAI,OAAO,KAAK,gCAAgC,MAAM,EAAE;AAAA,IAC1D,SAAS,KAAK;AACZ,UAAI,OAAO,MAAM,6BAA6B,MAAM,IAAI,EAAE,OAAO,OAAO,GAAG,EAAE,CAAC;AAC9E,YAAM,QAAQ,MAAM,IAAI,OAAO,OAAO;AAAA,QACpC,WAAWA,QAAO;AAAA,QAClB,OAAO,mCAAmC,MAAM;AAAA,QAChD,aAAa,6BAA6B,MAAM,QAAO,oBAAI,KAAK,GAAE,YAAY,CAAC;AAAA;AAAA,SAAe,OAAO,GAAG,CAAC;AAAA;AAAA;AAAA,MAC3G,CAAC;AACD,YAAM,IAAI,OAAO,OAAO,MAAM,IAAI,EAAE,QAAQ,OAAgB,GAAGA,QAAO,UAAU;AAAA,IAClF;AAAA,EACF;AACF;AAEA,eAAe,uBAAuB,KAAoB,MAAuC;AAC/F,QAAMA,UAAS,MAAM,UAAU,GAAG;AAElC,QAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,QAAM,WAAW,MAAM,IAAI,SAAS,KAAK,EAAE,YAAY,aAAa,OAAO,OAAO,IAAI,CAAC;AACvF,QAAM,MAAM,SAAS,OAAO,CAAC,MAAM;AACjC,UAAM,IAAI,EAAE;AACZ,WAAO,EAAE,eAAe,EAAE,eAAe,QAAQ,EAAE,WAAW,cAAc,EAAE,WAAW;AAAA,EAC3F,CAAC;AAED,aAAW,UAAU,KAAK;AACxB,UAAM,QAAQ,OAAO;AAGrB,UAAM,WAAW,eAAeA,SAAQ,MAAM,OAAO;AACrD,QAAI,CAAC,SAAS,IAAI;AAChB,UAAI,OAAO,MAAM,mBAAmB,OAAO,EAAE,KAAK,SAAS,KAAK,EAAE;AAClE;AAAA,IACF;AACA,UAAM,EAAE,QAAQ,QAAQ,IAAI;AAE5B,UAAM,WAAW,MAAM,cAAc,KAAKA,SAAQ,aAAa,OAAO,IAAI,QAAQ,cAAc;AAChG,QAAI,CAAC,SAAS,SAAS;AACrB,UAAI,OAAO,KAAK,mBAAmB,OAAO,EAAE,aAAa,SAAS,MAAM,EAAE;AAC1E;AAAA,IACF;AAEA,QAAI;AACF,YAAM,QAAQ,MAAM,oBAAoB,KAAKA,SAAQ,MAAM;AAE3D,UAAI,MAAM,WAAW,YAAY,MAAM,eAAe;AACpD,cAAM,cAAc,KAAK,OAAO,QAAQ,MAAM,eAAe,MAAM,UAAUA,QAAO,UAAU;AAAA,MAChG,OAAO;AACL,cAAM,SAAS,MAAM,YAAY,IAAI,MAAM,OAAO;AAAA,UAChD,MAAM,MAAM;AAAA,UACZ,UAAU,MAAM;AAAA,UAChB,gBAAgB,MAAM;AAAA,QACxB,CAAC;AACD,cAAM,iBAAiB,KAAK,QAAQ,eAAe,OAAO,SAAS;AAEnE,cAAM,IAAI,SAAS,OAAO;AAAA,UACxB,YAAY,aAAa;AAAA,UACzB,WAAW;AAAA,UACX,YAAY,OAAO,KAAK;AAAA,UACxB,OAAO,MAAM,KAAK,MAAM,GAAG,EAAE;AAAA,UAC7B,MAAM;AAAA,YACJ,UAAU,OAAO,KAAK;AAAA,YACtB,SAAS;AAAA,YACT,MAAM,OAAO,KAAK;AAAA,YAClB,eAAc,oBAAI,KAAK,GAAE,YAAY;AAAA,YACrC,UAAU,OAAO;AAAA,YACjB,QAAQ,MAAM;AAAA,YACd,UAAU,MAAM;AAAA,UAClB;AAAA,QACF,CAAC;AAED,cAAM,IAAI,OAAO,KAAK,YAAY,eAAeA,QAAO,YAAY;AAAA,UAClE,UAAU,OAAO,KAAK;AAAA,UACtB,MAAM,MAAM;AAAA,UACZ,QAAQ,MAAM;AAAA,UACd,UAAU,MAAM;AAAA,QAClB,CAAC;AAAA,MACH;AAGA,YAAM,SAAS;AACf,YAAM,IAAI,SAAS,OAAO;AAAA,QACxB,YAAY,aAAa;AAAA,QACzB,WAAW;AAAA,QACX,YAAY,OAAO,cAAc;AAAA,QACjC,OAAO,OAAO,SAAS,MAAM,KAAK,MAAM,GAAG,EAAE;AAAA,QAC7C,MAAM;AAAA,MACR,CAAC;AAED,UAAI,OAAO,KAAK,6BAA6B,OAAO,EAAE,EAAE;AAAA,IAC1D,SAAS,KAAK;AACZ,UAAI,OAAO,MAAM,qCAAqC,OAAO,EAAE,IAAI,EAAE,OAAO,OAAO,GAAG,EAAE,CAAC;AAAA,IAC3F;AAAA,EACF;AACF;AAEA,eAAe,qBAAqB,KAAoB,MAAuC;AAC7F,QAAMA,UAAS,MAAM,UAAU,GAAG;AAClC,QAAM,WAAW,eAAeA,OAAM;AACtC,MAAI,CAAC,SAAS,IAAI;AAAE,QAAI,OAAO,MAAM,SAAS,KAAK;AAAG;AAAA,EAAQ;AAC9D,QAAM,EAAE,OAAO,IAAI;AAEnB,QAAM,aAAaA,QAAO,gCAAgC;AAC1D,QAAM,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,UAAU,EAAE,YAAY;AAC7D,QAAM,WAAW,MAAM,IAAI,SAAS,KAAK,EAAE,YAAY,aAAa,eAAe,OAAO,IAAI,CAAC;AAC/F,QAAM,SAAS,SAAS,OAAO,CAAC,MAAM;AACpC,UAAM,IAAI,EAAE;AACZ,WAAO,EAAE,gBAAgB,UAAU,EAAE,WAAW;AAAA,EAClD,CAAC;AAED,MAAI,OAAO,WAAW,EAAG;AAEzB,QAAM,WAAW,OAAO,IAAI,CAAC,MAAO,EAAE,KAAsC,QAAQ;AACpF,QAAM,QAAQ,MAAM,oBAAoB,KAAKA,SAAQ,MAAM;AAE3D,QAAM,YAAY;AAClB,WAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK,WAAW;AACnD,UAAM,QAAQ,SAAS,MAAM,GAAG,IAAI,SAAS;AAC7C,UAAM,MAAM,kCAAkC,MAAM,KAAK,GAAG,CAAC;AAC7D,UAAM,OAAO,MAAM,IAAI,KAAK,MAAM,KAAK;AAAA,MACrC,SAAS,EAAE,eAAe,UAAU,KAAK,GAAG;AAAA,IAC9C,CAAC;AAED,QAAI,CAAC,KAAK,IAAI;AACZ,UAAI,OAAO,MAAM,gCAAgC,EAAE,QAAQ,KAAK,OAAO,CAAC;AACxE;AAAA,IACF;AAEA,UAAM,OAAQ,MAAM,KAAK,KAAK;AAC9B,QAAI,CAAC,KAAK,KAAM;AAEhB,eAAW,SAAS,KAAK,MAAM;AAC7B,YAAM,SAAS,OAAO,KAAK,CAAC,MAAO,EAAE,KAAsC,aAAa,MAAM,EAAE;AAChG,UAAI,CAAC,OAAQ;AAEb,YAAM,OAAO,OAAO;AACpB,YAAM,aAAa;AAAA,QACjB,OAAO,MAAM,eAAe;AAAA,QAC5B,UAAU,MAAM,eAAe;AAAA,QAC/B,SAAS,MAAM,eAAe;AAAA,QAC9B,aAAa,MAAM,eAAe,oBAAoB;AAAA,QACtD,cAAa,oBAAI,KAAK,GAAE,YAAY;AAAA,MACtC;AAGA,YAAM,kBAAkB,WAAW,QAAQ,WAAW,WAAW,WAAW;AAC5E,YAAM,YAAY,KAAK,UACnB,KAAK,QAAQ,QAAQ,KAAK,QAAQ,WAAW,KAAK,QAAQ,UAC1D;AAEJ,iBAAW,aAAaA,QAAO,uBAAuB;AACpD,YAAI,mBAAmB,aAAa,YAAY,WAAW;AACzD,gBAAM,IAAI,OAAO,KAAK,YAAY,yBAAyBA,QAAO,YAAY;AAAA,YAC5E,UAAU,MAAM;AAAA,YAChB;AAAA,YACA,iBAAiB;AAAA,UACnB,CAAC;AAAA,QACH;AAAA,MACF;AAEA,WAAK,UAAU;AACf,YAAM,IAAI,SAAS,OAAO;AAAA,QACxB,YAAY,aAAa;AAAA,QACzB,WAAW;AAAA,QACX,YAAY,OAAO,cAAc;AAAA,QACjC,OAAO,OAAO,SAAS,KAAK,KAAK,MAAM,GAAG,EAAE;AAAA,QAC5C;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAEA,MAAI,OAAO,KAAK,wBAAwB,OAAO,MAAM,QAAQ;AAC/D;AAEA,eAAe,wBAAwB,KAAoB,MAAuC;AAChG,QAAM,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,IAAO,EAAE,YAAY;AAC/D,QAAM,WAAW,MAAM,IAAI,SAAS,KAAK,EAAE,YAAY,aAAa,OAAO,OAAO,IAAI,CAAC;AACvF,MAAI,aAAa;AAEjB,aAAW,UAAU,UAAU;AAC7B,UAAM,OAAO,OAAO;AACpB,SAAK,KAAK,WAAW,WAAW,KAAK,WAAW,gBAAgB,OAAO,YAAY,QAAQ;AACzF,WAAK,SAAS;AACd,YAAM,IAAI,SAAS,OAAO;AAAA,QACxB,YAAY,aAAa;AAAA,QACzB,WAAW;AAAA,QACX,YAAY,OAAO,cAAc;AAAA,QACjC,OAAO,OAAO,SAAS,KAAK,KAAK,MAAM,GAAG,EAAE;AAAA,QAC5C;AAAA,MACF,CAAC;AACD;AAAA,IACF;AAAA,EACF;AAEA,MAAI,aAAa,GAAG;AAClB,QAAI,OAAO,KAAK,UAAU,UAAU,kBAAkB;AAAA,EACxD;AACF;AAMA,IAAI,YAAkC;AAEtC,IAAM,SAAS,aAAa;AAAA,EAC1B,MAAM,MAAM,KAAK;AACf,gBAAY;AAGZ,QAAI,KAAK,SAAS,SAAS,cAAc,CAAC,QAAQ,mBAAmB,KAAK,GAAG,CAAC;AAC9E,QAAI,KAAK,SAAS,SAAS,kBAAkB,CAAC,QAAQ,uBAAuB,KAAK,GAAG,CAAC;AACtF,QAAI,KAAK,SAAS,SAAS,gBAAgB,CAAC,QAAQ,qBAAqB,KAAK,GAAG,CAAC;AAClF,QAAI,KAAK,SAAS,SAAS,mBAAmB,CAAC,QAAQ,wBAAwB,KAAK,GAAG,CAAC;AAGxF,UAAM,IAAI,CAAC,WAAoB;AAC/B,QAAI,MAAM;AAAA,MACR,WAAW;AAAA,MACX,EAAE,aAAa,eAAe,aAAa,6BAA6B,kBAAkB,CAAC,EAAE;AAAA,MAC7F,CAAC,WAAW,iBAAiB,KAAK,EAAE,MAAM,CAAC;AAAA,IAC7C;AACA,QAAI,MAAM;AAAA,MACR,WAAW;AAAA,MACX,EAAE,aAAa,cAAc,aAAa,uBAAuB,kBAAkB,CAAC,EAAE;AAAA,MACtF,CAAC,WAAW,gBAAgB,KAAK,EAAE,MAAM,CAAC;AAAA,IAC5C;AACA,QAAI,MAAM;AAAA,MACR,WAAW;AAAA,MACX,EAAE,aAAa,gBAAgB,aAAa,yBAAyB,kBAAkB,CAAC,EAAE;AAAA,MAC1F,CAAC,WAAW,kBAAkB,KAAK,EAAE,MAAM,CAAC;AAAA,IAC9C;AACA,QAAI,MAAM;AAAA,MACR,WAAW;AAAA,MACX,EAAE,aAAa,gBAAgB,aAAa,4BAA4B,kBAAkB,CAAC,EAAE;AAAA,MAC7F,CAAC,WAAW,kBAAkB,KAAK,EAAE,MAAM,CAAC;AAAA,IAC9C;AACA,QAAI,MAAM;AAAA,MACR,WAAW;AAAA,MACX,EAAE,aAAa,gBAAgB,aAAa,wBAAwB,kBAAkB,CAAC,EAAE;AAAA,MACzF,CAAC,WAAW,kBAAkB,KAAK,EAAE,MAAM,CAAC;AAAA,IAC9C;AACA,QAAI,MAAM;AAAA,MACR,WAAW;AAAA,MACX,EAAE,aAAa,kBAAkB,aAAa,2BAA2B,kBAAkB,CAAC,EAAE;AAAA,MAC9F,CAAC,WAAW,mBAAmB,KAAK,EAAE,MAAM,CAAC;AAAA,IAC/C;AACA,QAAI,MAAM;AAAA,MACR,WAAW;AAAA,MACX,EAAE,aAAa,eAAe,aAAa,sBAAsB,kBAAkB,CAAC,EAAE;AAAA,MACtF,CAAC,WAAW,iBAAiB,KAAK,EAAE,MAAM,CAAC;AAAA,IAC7C;AACA,QAAI,MAAM;AAAA,MACR,WAAW;AAAA,MACX,EAAE,aAAa,UAAU,aAAa,kBAAkB,kBAAkB,CAAC,EAAE;AAAA,MAC7E,CAAC,WAAW,aAAa,KAAK,EAAE,MAAM,CAAC;AAAA,IACzC;AACA,QAAI,MAAM;AAAA,MACR,WAAW;AAAA,MACX,EAAE,aAAa,iBAAiB,aAAa,6BAA6B,kBAAkB,CAAC,EAAE;AAAA,MAC/F,CAAC,WAAW,mBAAmB,KAAK,EAAE,MAAM,CAAC;AAAA,IAC/C;AACA,QAAI,MAAM;AAAA,MACR,WAAW;AAAA,MACX,EAAE,aAAa,kBAAkB,aAAa,gCAAgC,kBAAkB,CAAC,EAAE;AAAA,MACnG,CAAC,WAAW,oBAAoB,KAAK,EAAE,MAAM,CAAC;AAAA,IAChD;AACA,QAAI,MAAM;AAAA,MACR,WAAW;AAAA,MACX,EAAE,aAAa,cAAc,aAAa,0BAA0B,kBAAkB,CAAC,EAAE;AAAA,MACzF,CAAC,WAAW,gBAAgB,KAAK,EAAE,MAAM,CAAC;AAAA,IAC5C;AACA,QAAI,MAAM;AAAA,MACR,WAAW;AAAA,MACX,EAAE,aAAa,gBAAgB,aAAa,gCAAgC,kBAAkB,CAAC,EAAE;AAAA,MACjG,CAAC,WAAW,kBAAkB,KAAK,EAAE,MAAM,CAAC;AAAA,IAC9C;AACA,QAAI,MAAM;AAAA,MACR,WAAW;AAAA,MACX,EAAE,aAAa,oBAAoB,aAAa,qCAAqC,kBAAkB,CAAC,EAAE;AAAA,MAC1G,CAAC,WAAW,qBAAqB,KAAK,EAAE,MAAM,CAAC;AAAA,IACjD;AACA,QAAI,MAAM;AAAA,MACR,WAAW;AAAA,MACX,EAAE,aAAa,sBAAsB,aAAa,kCAAkC,kBAAkB,CAAC,EAAE;AAAA,MACzG,CAAC,WAAW,uBAAuB,KAAK,EAAE,MAAM,CAAC;AAAA,IACnD;AAGA,QAAI,KAAK,SAAS,qBAAqB,YAAY;AACjD,YAAMA,UAAS,MAAM,UAAU,GAAG;AAClC,YAAM,WAAWA,QAAO,YAAY,CAAC;AACrC,YAAM,UAAU,OAAO,KAAK,QAAQ;AACpC,YAAM,SAAQ,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC;AACnD,YAAM,YAAY,MAAM,IAAI,SAAS,KAAK,EAAE,YAAY,aAAa,eAAe,OAAO,IAAI,CAAC;AAChG,YAAM,SAAS,MAAM,IAAI,SAAS,KAAK,EAAE,YAAY,aAAa,OAAO,OAAO,IAAI,CAAC;AAErF,YAAM,aAAa,UAAU;AAAA,QAAO,CAAC,MAClC,EAAE,KAAsC,aAAa,WAAW,KAAK;AAAA,MACxE;AAEA,YAAM,gBAAgB,OAAO,OAAO,CAAC,MAAM;AACzC,cAAM,IAAI,EAAE;AACZ,eAAO,EAAE,WAAW,WAAW,EAAE,WAAW,eAAe,EAAE,WAAW;AAAA,MAC1E,CAAC;AAGD,YAAM,gBAAwC,CAAC;AAC/C,iBAAW,UAAU,SAAS;AAC5B,YAAI;AACF,gBAAM,SAAS,MAAM,UAAU,KAAK,MAAM;AAC1C,wBAAc,MAAM,IAAI,OAAO,aAAa,KAAK,IAAI,IAAI,UAAU;AAAA,QACrE,QAAQ;AACN,wBAAc,MAAM,IAAI;AAAA,QAC1B;AAAA,MACF;AACA,YAAM,WAAW,OAAO,OAAO,aAAa,EAAE,MAAM,CAAC,MAAM,MAAM,OAAO;AACxE,YAAM,cAAc,QAAQ,WAAW,IAAI,gBAAgB,WAAW,UAAU;AAEhF,YAAM,cAAc,UACjB,IAAI,CAAC,MAAM,EAAE,IAAoC,EACjD,KAAK,CAAC,GAAG,MAAO,EAAE,eAAe,EAAE,eAAe,KAAK,CAAE,EACzD,MAAM,GAAG,CAAC;AAEb,aAAO;AAAA,QACL,kBAAkB,WAAW;AAAA,QAC7B,aAAaA,QAAO;AAAA,QACpB,gBAAgB,cAAc;AAAA,QAC9B,cAAc;AAAA,QACd,UAAU;AAAA,QACV,cAAc;AAAA,MAChB;AAAA,IACF,CAAC;AAED,QAAI,KAAK,SAAS,iBAAiB,YAAY;AAC7C,YAAMA,UAAS,MAAM,UAAU,GAAG;AAClC,aAAOA;AAAA,IACT,CAAC;AAED,QAAI,KAAK,SAAS,iBAAiB,YAAY;AAC7C,YAAM,YAAY,MAAM,IAAI,SAAS,KAAK,EAAE,YAAY,aAAa,OAAO,OAAO,IAAI,CAAC;AAExF,YAAM,UAAU,UACb,IAAI,CAAC,MAAM;AACV,cAAM,IAAI,EAAE;AACZ,eAAO,EAAE,IAAI,EAAE,IAAI,MAAM,EAAE,MAAM,QAAQ,EAAE,QAAQ,QAAQ,EAAE,QAAQ,aAAa,EAAE,YAAY;AAAA,MAClG,CAAC,EACA,OAAO,CAAC,OAAO,EAAE,WAAW,WAAW,EAAE,WAAW,eAAe,EAAE,WAAW,eAAe,CAAC,EAAE,WAAW;AAEhH,YAAM,YAAY,UACf,IAAI,CAAC,MAAM;AACV,cAAM,IAAI,EAAE;AACZ,eAAO,EAAE,IAAI,EAAE,IAAI,MAAM,EAAE,MAAM,QAAQ,EAAE,QAAQ,QAAQ,EAAE,QAAQ,aAAa,EAAE,YAAY;AAAA,MAClG,CAAC,EACA,OAAO,CAAC,MACP,CAAC,CAAC,EAAE,gBAAgB,EAAE,WAAW,WAAW,EAAE,WAAW,cAAc,EAAE,WAAW,YAAY,EACjG,KAAK,CAAC,GAAG,MAAO,EAAE,cAAc,EAAE,cAAc,IAAI,EAAG;AAE1D,aAAO,EAAE,QAAQ,SAAS,UAAU;AAAA,IACtC,CAAC;AAGD,QAAI,OAAO,GAAG,UAAU,aAAa,KAAK,IAAa,YAAY;AAAA,IAGnE,CAAC;AAED,QAAI,OAAO,KAAK,iCAAiC;AAAA,EACnD;AAAA,EAEA,MAAM,WAAW;AACf,QAAI,CAAC,UAAW,QAAO,EAAE,QAAQ,SAAkB,SAAS,yBAAyB;AAErF,UAAMA,UAAS,MAAM,UAAU,SAAS;AACxC,UAAM,WAAWA,QAAO,YAAY,CAAC;AACrC,UAAM,UAAU,OAAO,KAAK,QAAQ;AAEpC,QAAI,QAAQ,WAAW,GAAG;AACxB,aAAO,EAAE,QAAQ,SAAkB,SAAS,yBAAyB;AAAA,IACvE;AAEA,QAAI,SAAsC;AAC1C,UAAM,SAAmB,CAAC;AAC1B,UAAM,iBAA0C,CAAC;AAEjD,eAAW,UAAU,SAAS;AAC5B,YAAM,SAAkC,EAAE,MAAM,SAAS,MAAM,EAAG,KAAK;AACvE,UAAI;AACF,cAAM,SAAS,MAAM,UAAU,WAAW,MAAM;AAChD,cAAM,UAAU,OAAO,aAAa,KAAK,IAAI;AAC7C,cAAM,cAAc,KAAK,OAAO,OAAO,aAAa,KAAK,IAAI,KAAK,GAAK;AACvE,eAAO,QAAQ,UAAU,UAAU,WAAW,iBAAiB;AAC/D,YAAI,CAAC,SAAS;AACZ,cAAI,WAAW,KAAM,UAAS;AAC9B,iBAAO,KAAK,IAAI,MAAM,gBAAgB;AAAA,QACxC;AAAA,MACF,QAAQ;AACN,iBAAS;AACT,eAAO,KAAK,IAAI,MAAM,YAAY;AAClC,eAAO,QAAQ;AAAA,MACjB;AAEA,UAAI;AACF,cAAM,MAAM,MAAM,UAAU,MAAM,IAAID,UAAS,gBAAgB,WAAW,YAAY,MAAM,CAAC,CAAC;AAC9F,YAAI,KAAK;AACP,gBAAM,SAAS;AACf,iBAAO,cAAc,EAAE,WAAW,OAAO,aAAa,aAAa,WAAW,OAAO,OAAO,eAAe,EAAE;AAC7G,cAAI,OAAO,eAAe,OAAO,YAAY,cAAc,KAAK,OAAO,YAAY,WAAW,KAAK,IAAI,GAAG;AACxG,gBAAI,WAAW,KAAM,UAAS;AAC9B,mBAAO,KAAK,IAAI,MAAM,eAAe;AAAA,UACvC;AAAA,QACF;AAAA,MACF,QAAQ;AAAA,MAA+B;AAEvC,qBAAe,MAAM,IAAI;AAAA,IAC3B;AAEA,UAAM,UAAU,OAAO,SAAS,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,QAAQ,MAAM;AAC7E,WAAO,EAAE,QAAQ,SAAS,SAAS,EAAE,UAAU,eAAe,EAAE;AAAA,EAClE;AAAA,EAEA,MAAM,iBAAiBC,SAAiC;AACtD,UAAM,WAAqB,CAAC;AAC5B,UAAM,SAAmB,CAAC;AAE1B,UAAM,WAAYA,QAAO,YAAY,CAAC;AACtC,UAAM,UAAU,OAAO,KAAK,QAAQ;AAEpC,QAAI,QAAQ,WAAW,GAAG;AACxB,aAAO,KAAK,kDAAkD;AAAA,IAChE;AAEA,UAAM,cAAcA,QAAO;AAC3B,QAAI,eAAe,QAAQ,SAAS,KAAK,CAAC,SAAS,WAAW,GAAG;AAC/D,aAAO,KAAK,oBAAoB,WAAW,4CAA4C,QAAQ,KAAK,IAAI,CAAC,EAAE;AAAA,IAC7G;AAEA,eAAW,UAAU,SAAS;AAC5B,YAAM,OAAO,SAAS,MAAM;AAC5B,UAAI,CAAC,KAAK,SAAU,QAAO,KAAK,WAAW,MAAM,wBAAwB;AACzE,UAAI,CAAC,KAAK,UAAW,QAAO,KAAK,WAAW,MAAM,yBAAyB;AAAA,IAC7E;AAEA,QAAI,WAAW;AACb,YAAM,cAAeA,QAAO,uBAAkC,eAAe;AAC7E,YAAM,kBAAmBA,QAAO,2BAAsC,eAAe;AAErF,UAAI;AACF,cAAM,UAAU,QAAQ,QAAQ,WAAW;AAAA,MAC7C,QAAQ;AACN,eAAO,KAAK,8CAA8C;AAAA,MAC5D;AAEA,UAAI;AACF,cAAM,UAAU,QAAQ,QAAQ,eAAe;AAAA,MACjD,QAAQ;AACN,eAAO,KAAK,kDAAkD;AAAA,MAChE;AAEA,iBAAW,UAAU,SAAS;AAC5B,YAAI;AACF,gBAAM,UAAU,WAAW,MAAM;AAAA,QACnC,QAAQ;AACN,mBAAS,KAAK,wBAAwB,MAAM,8BAAyB;AAAA,QACvE;AAAA,MACF;AAAA,IACF;AAEA,WAAO,EAAE,IAAI,OAAO,WAAW,GAAG,UAAU,OAAO;AAAA,EACrD;AACF,CAAC;AAED,IAAO,iBAAQ;AACf,UAAU,QAAQ,YAAY,GAAG;",
|
|
6
|
+
"names": ["plugin", "config", "stateKey", "config", "stateKey", "config"]
|
|
7
7
|
}
|