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 CHANGED
@@ -1,6 +1,6 @@
1
1
  // src/constants.ts
2
2
  var PLUGIN_ID = "peak6-labs.x-publishing";
3
- var PLUGIN_VERSION = "0.2.2";
3
+ var PLUGIN_VERSION = "0.2.3";
4
4
  var TOOL_NAMES = {
5
5
  draftPost: "draft-post",
6
6
  updateDraft: "update-draft",
@@ -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, config, handle) {
968
+ async function refreshTokens(ctx, config2, handle) {
969
969
  const current = await getTokens(ctx, handle);
970
- const clientId = await ctx.secrets.resolve(config.oauth_client_id_ref);
971
- const clientSecret = await ctx.secrets.resolve(config.oauth_client_secret_ref);
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, config, handle) {
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, config, handle);
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, config, contentType, draftId, approvalModes) {
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: config.company_id,
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" }, config.company_id);
1154
- await ctx.events.emit(EVENT_NAMES.approvalRequired, config.company_id, {
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: config.company_id,
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" }, config.company_id);
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, config.company_id, {
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(config, handle) {
1267
- const accounts = config.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 || config.default_account || handles[0];
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 config = await getConfig(ctx);
1288
- const resolved = resolveAccount(config, handle);
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 config = await getConfig(ctx);
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, config.company_id, {
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 config = await getConfig(ctx);
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, config.company_id, {
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 config = await getConfig(ctx);
1386
- const resolved = resolveAccount(config, params.account);
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, config, "posts", draftId, account.approval_modes);
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, config, handle);
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, config.company_id, {
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 config = await getConfig(ctx);
1430
- const resolved = resolveAccount(config, params.account);
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, config, "replies", params.draft_id, account.approval_modes);
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, config, handle);
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, config.company_id, {
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 config = await getConfig(ctx);
1466
- const resolved = resolveAccount(config, params.account);
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, config, "quotes", params.draft_id, account.approval_modes);
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, config, handle);
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, config.company_id, {
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 config = await getConfig(ctx);
1502
- const resolved = resolveAccount(config, params.account);
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, config, "reposts", params.draft_id, account.approval_modes);
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, config, handle);
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, config.company_id, {
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 config = await getConfig(ctx);
1571
- const resolved = resolveAccount(config, params.account);
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, config, "posts", draftId, account.approval_modes);
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, config, handle);
1590
- const result = await publishThread(ctx, token, handle, threadTweets, metadata, config.company_id);
1591
- await ctx.events.emit(EVENT_NAMES.threadPublished, config.company_id, {
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, config.company_id, {
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 config = await getConfig(ctx);
1644
- const accounts = config.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: config.daily_post_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 config = await getConfig(ctx);
1684
- const handles = Object.keys(config.accounts || {});
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, config, handle);
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: config.company_id,
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" }, config.company_id);
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 config = await getConfig(ctx);
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 approval = await checkApproval(ctx, config, "scheduled", entity.id, resolved.account.approval_modes);
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, config, handle);
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, config.company_id);
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, config.company_id, {
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 config = await getConfig(ctx);
1773
- const resolved = resolveAccount(config);
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 = config.metrics_capture_lookback_days * 864e5;
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, config, handle);
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 config.engagement_milestones) {
1824
+ for (const milestone of config2.engagement_milestones) {
1816
1825
  if (totalEngagement >= milestone && prevTotal < milestone) {
1817
- await ctx.events.emit(EVENT_NAMES.postEngagementMilestone, config.company_id, {
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 config = await getConfig(ctx);
1939
- const accounts = config.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: config.daily_post_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 config = await getConfig(ctx);
1974
- return config;
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 config = await getConfig(pluginCtx);
1995
- const accounts = config.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(config) {
2045
+ async onValidateConfig(config2) {
2037
2046
  const warnings = [];
2038
2047
  const errors = [];
2039
- const accounts = config.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 = config.default_account;
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 = config.oauth_client_id_ref || DEFAULT_CONFIG.oauth_client_id_ref;
2055
- const clientSecretRef = config.oauth_client_secret_ref || DEFAULT_CONFIG.oauth_client_secret_ref;
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 {
@@ -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": ";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,KAAoB,QAA0B,QAAqC;AACrH,QAAM,UAAU,MAAM,UAAU,KAAK,MAAM;AAC3C,QAAM,WAAW,MAAM,IAAI,QAAQ,QAAQ,OAAO,mBAAmB;AACrE,QAAM,eAAe,MAAM,IAAI,QAAQ,QAAQ,OAAO,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,KAAoB,QAA0B,QAAiC;AACvH,QAAM,SAAS,MAAM,UAAU,KAAK,MAAM;AAE1C,MAAI,OAAO,aAAa,KAAK,IAAI,IAAI,mBAAmB;AACtD,UAAM,YAAY,MAAM,cAAc,KAAK,QAAQ,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,KACA,QACA,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,WAAW,OAAO;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,GAAG,OAAO,UAAU;AAEhF,UAAM,IAAI,OAAO,KAAK,YAAY,kBAAkB,OAAO,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,WAAW,OAAO;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,GAAG,OAAO,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,kBAAkB,OAAO,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,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;;;AC5CA,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,eACP,QACA,QACqF;AACrF,QAAM,WAAW,OAAO,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,UAAU,OAAO,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,QAAM,SAAS,MAAM,UAAU,GAAG;AAClC,QAAM,WAAW,eAAe,QAAQ,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,QAAM,SAAS,MAAM,UAAU,GAAG;AAClC,QAAM,SAAU,OAAO,UAAqB;AAC5C,QAAM,WAAY,OAAO,YAAsC,CAAC;AAEhE,QAAM,QAAmB;AAAA,IACvB;AAAA,IACA;AAAA,IACA,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,cAAc,OAAO,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,QAAM,SAAS,MAAM,UAAU,GAAG;AAClC,QAAM,WAAY,OAAO,YAAsC,CAAC;AAChE,QAAM,QAAmB;AAAA,IACvB,MAAM,aAAa,CAAC;AAAA,IACpB,QAAQ;AAAA,IACR,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,cAAc,OAAO,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,QAAM,SAAS,MAAM,UAAU,GAAG;AAClC,QAAM,WAAW,eAAe,QAAQ,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,KAAK,QAAQ,SAAS,SAAS,QAAQ,cAAc;AAC1F,MAAI,CAAC,SAAS,QAAS,QAAO,EAAE,OAAO,YAAY,SAAS,MAAM,GAAG;AAErE,QAAM,QAAQ,MAAM,oBAAoB,KAAK,QAAQ,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,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,eAAe,OAAO,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,QAAM,SAAS,MAAM,UAAU,GAAG;AAClC,QAAM,WAAW,eAAe,QAAQ,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,KAAK,QAAQ,WAAW,OAAO,UAAgC,QAAQ,cAAc;AAC1H,MAAI,CAAC,SAAS,QAAS,QAAO,EAAE,OAAO,YAAY,SAAS,MAAM,GAAG;AAErE,QAAM,QAAQ,MAAM,oBAAoB,KAAK,QAAQ,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,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,eAAe,OAAO,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,QAAM,SAAS,MAAM,UAAU,GAAG;AAClC,QAAM,WAAW,eAAe,QAAQ,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,KAAK,QAAQ,UAAU,OAAO,UAAgC,QAAQ,cAAc;AACzH,MAAI,CAAC,SAAS,QAAS,QAAO,EAAE,OAAO,YAAY,SAAS,MAAM,GAAG;AAErE,QAAM,QAAQ,MAAM,oBAAoB,KAAK,QAAQ,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,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,eAAe,OAAO,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,QAAM,SAAS,MAAM,UAAU,GAAG;AAClC,QAAM,WAAW,eAAe,QAAQ,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,KAAK,QAAQ,WAAW,OAAO,UAAgC,QAAQ,cAAc;AAC1H,MAAI,CAAC,SAAS,QAAS,QAAO,EAAE,OAAO,YAAY,SAAS,MAAM,GAAG;AAErE,QAAM,QAAQ,MAAM,oBAAoB,KAAK,QAAQ,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,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,eAAe,OAAO,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,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,QAAM,SAAS,MAAM,UAAU,GAAG;AAClC,QAAM,WAAW,eAAe,QAAQ,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,KAAK,QAAQ,SAAS,SAAS,QAAQ,cAAc;AAC1F,MAAI,CAAC,SAAS,QAAS,QAAO,EAAE,OAAO,YAAY,SAAS,MAAM,GAAG;AAErE,QAAM,QAAQ,MAAM,oBAAoB,KAAK,QAAQ,MAAM;AAC3D,QAAM,SAAS,MAAM,cAAc,KAAK,OAAO,QAAQ,cAAc,UAAU,OAAO,UAAU;AAEhG,QAAM,IAAI,OAAO,KAAK,YAAY,iBAAiB,OAAO,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,eAAe,OAAO,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,QAAM,SAAS,MAAM,UAAU,GAAG;AAClC,QAAM,WAAW,OAAO,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,IAAIA,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;AAAA,IAC3C,CAAC,EAAE;AAEH,aAAS,KAAK;AAAA,MACZ,UAAU;AAAA,MACV,MAAM,SAAS,MAAM,GAAG,QAAQ;AAAA,MAChC,cAAc;AAAA,MACd,aAAa,EAAE,OAAO,YAAY,OAAO,OAAO,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,QAAM,SAAS,MAAM,UAAU,GAAG;AAClC,QAAM,UAAU,OAAO,KAAK,OAAO,YAAY,CAAC,CAAC;AAEjD,aAAW,UAAU,SAAS;AAC5B,QAAI;AACF,YAAM,cAAc,KAAK,QAAQ,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,WAAW,OAAO;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,GAAG,OAAO,UAAU;AAAA,IAClF;AAAA,EACF;AACF;AAEA,eAAe,uBAAuB,KAAoB,MAAuC;AAC/F,QAAM,SAAS,MAAM,UAAU,GAAG;AAClC,QAAM,WAAW,eAAe,MAAM;AACtC,MAAI,CAAC,SAAS,IAAI;AAAE,QAAI,OAAO,MAAM,SAAS,KAAK;AAAG;AAAA,EAAQ;AAC9D,QAAM,EAAE,OAAO,IAAI;AAEnB,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;AACrB,UAAM,WAAW,MAAM,cAAc,KAAK,QAAQ,aAAa,OAAO,IAAI,SAAS,QAAQ,cAAc;AACzG,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,KAAK,QAAQ,MAAM;AAE3D,UAAI,MAAM,WAAW,YAAY,MAAM,eAAe;AACpD,cAAM,cAAc,KAAK,OAAO,MAAM,eAAe,MAAM,UAAU,OAAO,UAAU;AAAA,MACxF,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,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,eAAe,OAAO,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,QAAM,SAAS,MAAM,UAAU,GAAG;AAClC,QAAM,WAAW,eAAe,MAAM;AACtC,MAAI,CAAC,SAAS,IAAI;AAAE,QAAI,OAAO,MAAM,SAAS,KAAK;AAAG;AAAA,EAAQ;AAC9D,QAAM,EAAE,OAAO,IAAI;AAEnB,QAAM,aAAa,OAAO,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,KAAK,QAAQ,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,aAAa,OAAO,uBAAuB;AACpD,YAAI,mBAAmB,aAAa,YAAY,WAAW;AACzD,gBAAM,IAAI,OAAO,KAAK,YAAY,yBAAyB,OAAO,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,YAAM,SAAS,MAAM,UAAU,GAAG;AAClC,YAAM,WAAW,OAAO,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,aAAa,OAAO;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,YAAM,SAAS,MAAM,UAAU,GAAG;AAClC,aAAO;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,UAAM,SAAS,MAAM,UAAU,SAAS;AACxC,UAAM,WAAW,OAAO,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,IAAIA,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,iBAAiB,QAAiC;AACtD,UAAM,WAAqB,CAAC;AAC5B,UAAM,SAAmB,CAAC;AAE1B,UAAM,WAAY,OAAO,YAAY,CAAC;AACtC,UAAM,UAAU,OAAO,KAAK,QAAQ;AAEpC,QAAI,QAAQ,WAAW,GAAG;AACxB,aAAO,KAAK,kDAAkD;AAAA,IAChE;AAEA,UAAM,cAAc,OAAO;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,cAAe,OAAO,uBAAkC,eAAe;AAC7E,YAAM,kBAAmB,OAAO,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", "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": "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",
6
+ "names": ["plugin", "config", "stateKey", "config", "stateKey", "config"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "peak6-x-publishing-plugin",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "type": "module",
5
5
  "description": "X/Twitter publishing plugin for Paperclip",
6
6
  "repository": {