peak6-x-publishing-plugin 0.2.1 → 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.1";
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.1\";\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
  }