{"id":"663d8aea-ff18-460e-8801-b6639f87e56f","entityType":"agent","slug":"clawhub-madebydia-xqueue","name":"Xqueue","canonicalUrl":"https://www.xpersona.co/agent/clawhub-madebydia-xqueue","canonicalPath":"/agent/clawhub-madebydia-xqueue","generatedAt":"2026-10-10T10:42:24.988Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"editorial-content","verified":true,"confidence":"high","updatedAt":"2026-10-10T05:47:51.138Z","emptyReason":null},"description":"File-based X/Twitter post scheduler. Drop tweets into day/time folders, they post automatically. No frontend, no app — your file system is the UI. Skill: Xqueue Owner: madebydia Summary: File-based X/Twitter post scheduler. Drop tweets into day/time folders, they post automatically. No frontend, no app — your file system is the UI. Tags: latest:1.0.6 Version history: v1.0.6 | 2026-06-07T03:31:53.047Z | user Refresh publisher identity and metadata for madebydia v1.0.5 | 2026-03-27T16:00:31.523Z | user Cross-list sync from workspace v1.0.4 | 2026-03-24T16:58:12.6","descriptionLabel":"Technical summary","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 1.6K downloads reported by the source. Last updated 10/10/2026.","installCommand":"clawhub skill install s176b3312npmthbt2chf2mccw183grfh:xqueue","sourceUrl":"https://clawhub.ai/madebydia/xqueue","homepage":"https://clawhub.ai/madebydia/skills/xqueue","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/madebydia/xqueue","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/madebydia/skills/xqueue","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":55,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"File-based X/Twitter post scheduler. Drop tweets into day/time folders, they post automatically. No frontend, no app — your file system is the UI. Skill: Xqueue"},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-10T05:47:51.138Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T05:47:51.138Z","emptyReason":null},"stars":null,"forks":null,"downloads":1642,"packageName":null,"latestVersion":"1.0.6","tractionLabel":"1.6K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-10T05:47:51.138Z","emptyReason":null},"lastUpdatedAt":"2026-10-10T05:47:51.138Z","lastCrawledAt":"2026-10-10T05:47:51.138Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-11T05:47:51.138Z","lastVerifiedAt":null,"highlights":[{"version":"1.0.6","createdAt":"2026-06-07T03:31:53.047Z","changelog":"Refresh publisher identity and metadata for madebydia","fileCount":6,"zipByteSize":12975},{"version":"1.0.5","createdAt":"2026-03-27T16:00:31.523Z","changelog":"Cross-list sync from workspace","fileCount":6,"zipByteSize":13722},{"version":"1.0.4","createdAt":"2026-03-24T16:58:12.602Z","changelog":"Fixed permissions scope declaration — now accurately declares macOS Keychain and openclaw CLI access to resolve ClawHub security scanner scope mismatch","fileCount":5,"zipByteSize":12479},{"version":"1.0.3","createdAt":"2026-03-24T15:32:39.105Z","changelog":"Security: replaced hand-rolled OAuth 1.0a with requests-oauthlib, fixed path traversal in setup script","fileCount":5,"zipByteSize":12407},{"version":"1.0.2","createdAt":"2026-02-24T18:36:08.123Z","changelog":"Fix metadata format","fileCount":5,"zipByteSize":11658},{"version":"1.0.1","createdAt":"2026-02-23T18:30:13.148Z","changelog":"Fix security scan: declare required credentials in metadata, sanitize logFile path, remove hardcoded keychain account","fileCount":5,"zipByteSize":11671},{"version":"1.0.0","createdAt":"2026-02-23T14:30:11.890Z","changelog":"Initial release — file-based X/Twitter post scheduler","fileCount":5,"zipByteSize":11145}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s176b3312npmthbt2chf2mccw183grfh:xqueue","setupComplexity":"low","setupSteps":["Setup complexity is classified as HIGH. You must provision dedicated cloud infrastructure or an isolated VM. Do not run this directly on your local workstation.","Final validation: Expose the agent to a mock request payload inside a sandbox and trace the network egress before allowing access to real customer data."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-madebydia-xqueue/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-madebydia-xqueue/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-madebydia-xqueue/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-madebydia-xqueue/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-madebydia-xqueue/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-madebydia-xqueue/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-10T10:42:24.986Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-madebydia-xqueue/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-madebydia-xqueue/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-madebydia-xqueue/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-madebydia-xqueue/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"high","updatedAt":"2026-10-10T05:47:51.138Z","emptyReason":null},"readme":"Skill: Xqueue\n\nOwner: madebydia\n\nSummary: File-based X/Twitter post scheduler. Drop tweets into day/time folders, they post automatically. No frontend, no app — your file system is the UI.\n\nTags: latest:1.0.6\n\nVersion history:\n\nv1.0.6 | 2026-06-07T03:31:53.047Z | user\n\nRefresh publisher identity and metadata for madebydia\n\nv1.0.5 | 2026-03-27T16:00:31.523Z | user\n\nCross-list sync from workspace\n\nv1.0.4 | 2026-03-24T16:58:12.602Z | user\n\nFixed permissions scope declaration — now accurately declares macOS Keychain and openclaw CLI access to resolve ClawHub security scanner scope mismatch\n\nv1.0.3 | 2026-03-24T15:32:39.105Z | user\n\nSecurity: replaced hand-rolled OAuth 1.0a with requests-oauthlib, fixed path traversal in setup script\n\nv1.0.2 | 2026-02-24T18:36:08.123Z | user\n\nFix metadata format\n\nv1.0.1 | 2026-02-23T18:30:13.148Z | user\n\nFix security scan: declare required credentials in metadata, sanitize logFile path, remove hardcoded keychain account\n\nv1.0.0 | 2026-02-23T14:30:11.890Z | user\n\nInitial release — file-based X/Twitter post scheduler\n\nArchive index:\n\nArchive v1.0.6: 6 files, 12975 bytes\n\nFiles: README.md (2473b), skill-card.md (2310b), SKILL.md (5997b), xqueue-post.py (15318b), xqueue-setup.py (5469b), _meta.json (125b)\n\nFile v1.0.6:SKILL.md\n\n---\nname: xqueue\ndescription: File-based X/Twitter post scheduler. Drop tweets into day/time folders, they post automatically. No frontend, no app — your file system is the UI.\nmetadata: {\"openclaw\":{\"requires\":{\"env\":[\"X_CONSUMER_KEY\",\"X_CONSUMER_SECRET\",\"X_ACCESS_TOKEN\",\"X_ACCESS_TOKEN_SECRET\"],\"bins\":[\"python3\"]},\"permissions\":{\"filesystem\":\"read/write within xqueue/ directory\",\"network\":\"api.twitter.com, upload.twitter.com\",\"keychain\":\"optional macOS Keychain if XQUEUE_KEYCHAIN_ACCOUNT is set\"},\"homepage\":\"https://github.com/madebydia/xqueue\",\"author\":\"Diana Park (@madebydia)\"}}\n---\n\n# XQueue\n\nA file-based post scheduler for X (Twitter). Your file system is the UI.\n\n## How It Works\n\nCreate a folder structure with days and times. Drop tweet files into the time slots. A cron job checks every 15 minutes — if it's the right day and time and there's content, it posts and cleans up.\n\n```\nxqueue/\n  config.json\n  backlog/\n    ebook-launch-thread.md\n    ai-tools-roundup.md\n  Sunday/\n    10am/\n      my-tweet.md\n      photo.jpg\n  Monday/\n    9am/\n      thread-about-shipping.md\n    12pm/\n    5pm/\n  Tuesday/\n    ...\n```\n\nThe schedule cycles weekly. Monday's 9am slot fires every Monday at 9am. If the folder is empty, it pulls the oldest file from `backlog/` (sorted alphabetically). If there's content in the slot, it posts that and backlog waits. This means you can schedule up to a week of specific content, and dump everything else in backlog — it'll fill empty slots automatically.\n\nAfter posting, files are deleted (by default) so they don't repeat.\n\n## Setup\n\nRun the setup command to create your queue:\n\n```bash\npython3 xqueue-setup.py\n```\n\nThis asks you:\n1. How many times per day do you want to post?\n2. What times? (or let it pick optimal times)\n3. What timezone?\n4. Any X communities to post to?\n5. Thread separator preference (default: ---)\n6. Delete after posting? (recommended yes — if off, posts may send twice)\n\nCreates the full folder structure + config.json.\n\n## Tweet Format\n\n### Simple tweet\nJust write the text in a `.md` or `.txt` file:\n\n```\nThis is my tweet. It can be up to 280 characters.\n```\n\n### Tweet with community\nStart with `Post to [community name]:` on the first line:\n\n```\nPost to Build in Public: Just shipped my first ClawHub skill. File-based tweet scheduler, no frontend needed.\n```\n\n### Thread\nOne file, tweets separated by your configured separator (default `---`):\n\n```\nI built a file-based tweet scheduler with no frontend. Your filesystem is the UI.\n---\nDrop a .md file into Monday/9am/ and a cron job posts it. Empty slot? It pulls from a backlog/ folder automatically.\n---\nNo database, no app, no dashboard. Just folders and text files. Sometimes the simplest architecture wins.\n```\n\n### Tweet with media\nPut image/video files in the same time folder as the tweet. Supported: JPG, PNG, GIF (under 5MB for images, 15MB for GIF).\n\n```\n9am/\n  tweet.md        ← the text\n  progress.png    ← gets attached\n```\n\nIf multiple media files exist, they attach in alphabetical order (max 4 per tweet).\n\n## Config\n\n`xqueue/config.json`:\n\n```json\n{\n  \"timezone\": \"America/Chicago\",\n  \"separator\": \"---\",\n  \"deleteAfterPost\": true,\n  \"communities\": {\n    \"Build in Public\": \"community_id\",\n    \"Indie Hackers\": \"community_id\"\n  },\n  \"logFile\": \"xqueue/posted.log\",\n  \"dryRun\": false\n}\n```\n\nDuring setup, paste the community URL (like `x.com/i/communities/123456`) or the numeric ID directly. The script extracts the ID and asks for a display name. Plain names without an ID are rejected — everything needed to post is captured upfront.\n\n## Backlog\n\nThe `xqueue/backlog/` folder holds tweets that aren't scheduled for a specific slot. When the cron fires and a time slot is empty, it pulls the oldest file from backlog (alphabetical sort — prefix with numbers like `01-`, `02-` to control order).\n\nThis lets you batch-write content without worrying about fitting it into exactly the right number of weekly slots. Schedule what's time-sensitive, backlog the rest.\n\n## Cron Integration\n\nThe skill includes a cron job that runs every 15 minutes:\n- Checks current day + time against folder structure\n- If slot has content → post it\n- If slot is empty → pull oldest from `backlog/`\n- If both are empty → skip\n- Logs results to posted.log\n- Deletes posted files (if deleteAfterPost is on)\n\n## What Goes Where\n\n| You want to...                        | Do this                                               |\n| ------------------------------------- | ----------------------------------------------------- |\n| Schedule a tweet for Tuesday 9am      | Drop a .md file in `xqueue/Tuesday/9am/`              |\n| Post a thread                         | One .md file with `---` between tweets                |\n| Attach an image                       | Put the image file in the same folder as the .md file |\n| Post to a community                   | Start text with `Post to Community Name:`             |\n| Reorder posts                         | Move files between time folders                       |\n| Skip a time slot                      | Leave the folder empty                                |\n| See what's queued                     | Browse the xqueue folder                              |\n| See what already posted               | Check xqueue/posted.log                               |\n| Queue content without a specific time | Drop it in `xqueue/backlog/`                          |\n| Control backlog order                 | Prefix filenames: `01-first.md`, `02-second.md`       |\n\n## Important\n\n- **deleteAfterPost: true** (default) means each file posts once then gets removed. If you turn this off, the same content will post again next week when the cycle repeats.\n- Tweets over 280 characters are rejected (logged as error, not posted).\n- Thread tweets are each checked for 280 char limit individually.\n- Empty folders are silently skipped.\n- The cron checks every 15 minutes, so posts go out within 0-15 min of the scheduled time.\n\nFile v1.0.6:README.md\n\n# XQueue\n\nA file-based post scheduler for X (Twitter). Your file system is the UI.\n\nNo database. No dashboard. No app. Just folders, text files, and a cron job.\n\n## How It Works\n\n```\nxqueue/\n  config.json\n  backlog/\n  Monday/\n    9am/\n      thread-about-shipping.md\n    12pm/\n    5pm/\n  Tuesday/\n    ...\n```\n\n- **Drop a `.md` file into a day/time folder** → it posts at that time\n- **Empty slot?** → pulls the oldest file from `backlog/` automatically\n- **Schedule cycles weekly** → Monday/9am fires every Monday at 9am\n- **Files are deleted after posting** (configurable) so nothing repeats\n\n## Setup\n\n```bash\npython3 xqueue-setup.py\n```\n\nThe setup wizard asks how many daily posts, what times, timezone, and optional X community targets (paste the community URL, it extracts the ID). Creates the full folder structure + `config.json`.\n\n## Tweet Formats\n\n**Simple tweet** — just text in a `.md` file:\n```\nJust shipped v2. Sometimes the simplest architecture wins.\n```\n\n**Thread** — one file, `---` between tweets:\n```\nI built a file-based tweet scheduler with no frontend. Your filesystem is the UI.\n---\nDrop a .md file into Monday/9am/ and a cron job posts it. Empty slot? It pulls from backlog automatically.\n---\nNo database, no app, no dashboard. Just folders and text files.\n```\n\n**With media** — put images in the same folder (max 4, alphabetical order):\n```\n9am/\n  tweet.md\n  screenshot.png\n```\n\n**Community post** — prefix with the community name:\n```\nPost to Build in Public: Just shipped my first skill. File-based tweet scheduler, no frontend needed.\n```\n\n## Backlog\n\nThe `backlog/` folder holds content without a specific time slot. When a scheduled slot is empty, the oldest backlog file gets posted. Prefix filenames with numbers (`01-`, `02-`) to control order.\n\nWrite a week of content in one sitting, dump it in backlog, and it distributes itself across your empty slots.\n\n## Cron\n\nDesigned to run on a 15-minute cron cycle. Each tick:\n1. Checks current day + time against folder structure\n2. Posts slot content (or pulls from backlog if empty)\n3. Logs to `posted.log`\n4. Cleans up posted files\n\n## Requirements\n\n- Python 3\n- X API credentials via environment variables:\n  - `X_CONSUMER_KEY`, `X_CONSUMER_SECRET` (app credentials)\n  - `X_ACCESS_TOKEN`, `X_ACCESS_TOKEN_SECRET` (user credentials)\n  - Optional: set `XQUEUE_KEYCHAIN_ACCOUNT` to use macOS Keychain as fallback\n- A cron runner (OpenClaw cron, system cron, etc.)\n\n## License\n\nMIT\n\nFile v1.0.6:_meta.json\n\n{\n  \"ownerId\": \"kn711gxkbyw34qye3faaqw24yn8163fm\",\n  \"slug\": \"xqueue\",\n  \"version\": \"1.0.6\",\n  \"publishedAt\": 1780803113047\n}\n\nFile v1.0.6:skill-card.md\n\n## Description:\n\nFile-based X/Twitter post scheduler. Drop tweets into day/time folders, they post automatically. No frontend, no app - your file system is the UI.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[madebydia](https://clawhub.ai/user/madebydia)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nExternal users and developers use Xqueue to schedule X/Twitter posts, threads, media posts, and community posts by placing text and media files into day and time folders. It is intended for personal or team social posting workflows that can be run from cron with X API credentials.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: A queue-isolation weakness could allow symlinked files outside the queue to be posted to X under the user's account.\n\nMitigation: Use a private queue directory that untrusted users and processes cannot write to, and avoid symlinks in the queue.\n\nRisk: When deleteAfterPost is enabled, successfully posted content and media are removed after posting.\n\nMitigation: Keep backups of scheduled content and media if retaining originals matters.\n\nRisk: The skill can post scheduled content and media to X using the user's account credentials.\n\nMitigation: Review queued files before enabling cron, start with dryRun when validating setup, and only provide credentials for an account authorized for this posting workflow.\n\n## Reference(s):\n\n- [ClawHub Skill Page](https://clawhub.ai/madebydia/skills/xqueue)\n- [Xqueue Homepage](https://github.com/madebydia/xqueue)\n\n## Skill Output:\n\n**Output Type(s):** [guidance, shell commands, configuration]\n\n**Output Format:** [Markdown guidance with shell commands and JSON configuration examples]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Produces setup and operating guidance for a local file-based queue; posting behavior depends on the user's configured cron schedule, queue contents, and X API credentials.]\n\n## Skill Version(s):\n\n1.0.6 (source: server-resolved release metadata)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v1.0.5: 6 files, 13722 bytes\n\nFiles: README.md (2473b), skill-card.md (2262b), SKILL.md (6089b), xqueue-post.py (16654b), xqueue-setup.py (6007b), _meta.json (125b)\n\nFile v1.0.5:SKILL.md\n\n---\nname: xqueue\ndescription: File-based X/Twitter post scheduler. Drop tweets into day/time folders, they post automatically. No frontend, no app — your file system is the UI.\nmetadata: {\"openclaw\":{\"requires\":{\"env\":[\"X_CONSUMER_KEY\",\"X_CONSUMER_SECRET\",\"X_ACCESS_TOKEN\",\"X_ACCESS_TOKEN_SECRET\"],\"bins\":[\"python3\"],\"pip\":[\"requests\",\"requests-oauthlib\"]},\"permissions\":{\"filesystem\":\"read/write within xqueue/ directory, ~/.openclaw/workspace/xqueue/notifications.log\",\"network\":\"api.x.com, upload.twitter.com\",\"keychain\":\"macOS Keychain for X API credentials (fallback when env vars not set)\",\"system\":\"openclaw CLI wake command for notifications (best-effort, non-critical)\"}}}\n---\n\n# XQueue\n\nA file-based post scheduler for X (Twitter). Your file system is the UI.\n\n## How It Works\n\nCreate a folder structure with days and times. Drop tweet files into the time slots. A cron job checks every 15 minutes — if it's the right day and time and there's content, it posts and cleans up.\n\n```\nxqueue/\n  config.json\n  backlog/\n    ebook-launch-thread.md\n    ai-tools-roundup.md\n  Sunday/\n    10am/\n      my-tweet.md\n      photo.jpg\n  Monday/\n    9am/\n      thread-about-shipping.md\n    12pm/\n    5pm/\n  Tuesday/\n    ...\n```\n\nThe schedule cycles weekly. Monday's 9am slot fires every Monday at 9am. If the folder is empty, it pulls the oldest file from `backlog/` (sorted alphabetically). If there's content in the slot, it posts that and backlog waits. This means you can schedule up to a week of specific content, and dump everything else in backlog — it'll fill empty slots automatically.\n\nAfter posting, files are deleted (by default) so they don't repeat.\n\n## Setup\n\nRun the setup command to create your queue:\n\n```bash\npython3 xqueue-setup.py\n```\n\nThis asks you:\n1. How many times per day do you want to post?\n2. What times? (or let it pick optimal times)\n3. What timezone?\n4. Any X communities to post to?\n5. Thread separator preference (default: ---)\n6. Delete after posting? (recommended yes — if off, posts may send twice)\n\nCreates the full folder structure + config.json.\n\n## Tweet Format\n\n### Simple tweet\nJust write the text in a `.md` or `.txt` file:\n\n```\nThis is my tweet. It can be up to 280 characters.\n```\n\n### Tweet with community\nStart with `Post to [community name]:` on the first line:\n\n```\nPost to Build in Public: Just shipped my first ClawHub skill. File-based tweet scheduler, no frontend needed.\n```\n\n### Thread\nOne file, tweets separated by your configured separator (default `---`):\n\n```\nI built a file-based tweet scheduler with no frontend. Your filesystem is the UI.\n---\nDrop a .md file into Monday/9am/ and a cron job posts it. Empty slot? It pulls from a backlog/ folder automatically.\n---\nNo database, no app, no dashboard. Just folders and text files. Sometimes the simplest architecture wins.\n```\n\n### Tweet with media\nPut image/video files in the same time folder as the tweet. Supported: JPG, PNG, GIF (under 5MB for images, 15MB for GIF).\n\n```\n9am/\n  tweet.md        ← the text\n  progress.png    ← gets attached\n```\n\nIf multiple media files exist, they attach in alphabetical order (max 4 per tweet).\n\n## Config\n\n`xqueue/config.json`:\n\n```json\n{\n  \"timezone\": \"America/Chicago\",\n  \"separator\": \"---\",\n  \"deleteAfterPost\": true,\n  \"communities\": {\n    \"Build in Public\": \"community_id\",\n    \"Indie Hackers\": \"community_id\"\n  },\n  \"logFile\": \"xqueue/posted.log\",\n  \"dryRun\": false\n}\n```\n\nDuring setup, paste the community URL (like `x.com/i/communities/123456`) or the numeric ID directly. The script extracts the ID and asks for a display name. Plain names without an ID are rejected — everything needed to post is captured upfront.\n\n## Backlog\n\nThe `xqueue/backlog/` folder holds tweets that aren't scheduled for a specific slot. When the cron fires and a time slot is empty, it pulls the oldest file from backlog (alphabetical sort — prefix with numbers like `01-`, `02-` to control order).\n\nThis lets you batch-write content without worrying about fitting it into exactly the right number of weekly slots. Schedule what's time-sensitive, backlog the rest.\n\n## Cron Integration\n\nThe skill includes a cron job that runs every 15 minutes:\n- Checks current day + time against folder structure\n- If slot has content → post it\n- If slot is empty → pull oldest from `backlog/`\n- If both are empty → skip\n- Logs results to posted.log\n- Deletes posted files (if deleteAfterPost is on)\n\n## What Goes Where\n\n| You want to...                        | Do this                                               |\n| ------------------------------------- | ----------------------------------------------------- |\n| Schedule a tweet for Tuesday 9am      | Drop a .md file in `xqueue/Tuesday/9am/`              |\n| Post a thread                         | One .md file with `---` between tweets                |\n| Attach an image                       | Put the image file in the same folder as the .md file |\n| Post to a community                   | Start text with `Post to Community Name:`             |\n| Reorder posts                         | Move files between time folders                       |\n| Skip a time slot                      | Leave the folder empty                                |\n| See what's queued                     | Browse the xqueue folder                              |\n| See what already posted               | Check xqueue/posted.log                               |\n| Queue content without a specific time | Drop it in `xqueue/backlog/`                          |\n| Control backlog order                 | Prefix filenames: `01-first.md`, `02-second.md`       |\n\n## Important\n\n- **deleteAfterPost: true** (default) means each file posts once then gets removed. If you turn this off, the same content will post again next week when the cycle repeats.\n- Tweets over 280 characters are rejected (logged as error, not posted).\n- Thread tweets are each checked for 280 char limit individually.\n- Empty folders are silently skipped.\n- The cron checks every 15 minutes, so posts go out within 0-15 min of the scheduled time.\n\nFile v1.0.5:README.md\n\n# XQueue\n\nA file-based post scheduler for X (Twitter). Your file system is the UI.\n\nNo database. No dashboard. No app. Just folders, text files, and a cron job.\n\n## How It Works\n\n```\nxqueue/\n  config.json\n  backlog/\n  Monday/\n    9am/\n      thread-about-shipping.md\n    12pm/\n    5pm/\n  Tuesday/\n    ...\n```\n\n- **Drop a `.md` file into a day/time folder** → it posts at that time\n- **Empty slot?** → pulls the oldest file from `backlog/` automatically\n- **Schedule cycles weekly** → Monday/9am fires every Monday at 9am\n- **Files are deleted after posting** (configurable) so nothing repeats\n\n## Setup\n\n```bash\npython3 xqueue-setup.py\n```\n\nThe setup wizard asks how many daily posts, what times, timezone, and optional X community targets (paste the community URL, it extracts the ID). Creates the full folder structure + `config.json`.\n\n## Tweet Formats\n\n**Simple tweet** — just text in a `.md` file:\n```\nJust shipped v2. Sometimes the simplest architecture wins.\n```\n\n**Thread** — one file, `---` between tweets:\n```\nI built a file-based tweet scheduler with no frontend. Your filesystem is the UI.\n---\nDrop a .md file into Monday/9am/ and a cron job posts it. Empty slot? It pulls from backlog automatically.\n---\nNo database, no app, no dashboard. Just folders and text files.\n```\n\n**With media** — put images in the same folder (max 4, alphabetical order):\n```\n9am/\n  tweet.md\n  screenshot.png\n```\n\n**Community post** — prefix with the community name:\n```\nPost to Build in Public: Just shipped my first skill. File-based tweet scheduler, no frontend needed.\n```\n\n## Backlog\n\nThe `backlog/` folder holds content without a specific time slot. When a scheduled slot is empty, the oldest backlog file gets posted. Prefix filenames with numbers (`01-`, `02-`) to control order.\n\nWrite a week of content in one sitting, dump it in backlog, and it distributes itself across your empty slots.\n\n## Cron\n\nDesigned to run on a 15-minute cron cycle. Each tick:\n1. Checks current day + time against folder structure\n2. Posts slot content (or pulls from backlog if empty)\n3. Logs to `posted.log`\n4. Cleans up posted files\n\n## Requirements\n\n- Python 3\n- X API credentials via environment variables:\n  - `X_CONSUMER_KEY`, `X_CONSUMER_SECRET` (app credentials)\n  - `X_ACCESS_TOKEN`, `X_ACCESS_TOKEN_SECRET` (user credentials)\n  - Optional: set `XQUEUE_KEYCHAIN_ACCOUNT` to use macOS Keychain as fallback\n- A cron runner (OpenClaw cron, system cron, etc.)\n\n## License\n\nMIT\n\nFile v1.0.5:_meta.json\n\n{\n  \"ownerId\": \"kn711gxkbyw34qye3faaqw24yn8163fm\",\n  \"slug\": \"xqueue\",\n  \"version\": \"1.0.5\",\n  \"publishedAt\": 1774627231523\n}\n\nFile v1.0.5:skill-card.md\n\n## Description: <br>\nFile-based X/Twitter post scheduler. Drop tweets into day/time folders, they post automatically. No frontend, no app - your file system is the UI. <br>\n\nThis skill is ready for commercial/non-commercial use. <br>\n\n## Publisher: <br>\n[meimakes](https://clawhub.ai/user/meimakes) <br>\n\n### License/Terms of Use: <br>\nMIT-0 <br>\n\n\n## Use Case: <br>\nDevelopers and content operators use this skill to maintain a folder-based queue of X/Twitter posts, threads, media posts, and community posts that a scheduled runner publishes automatically. <br>\n\n### Deployment Geography for Use: <br>\nGlobal <br>\n\n## Known Risks and Mitigations: <br>\nRisk: Queued files can become public X/Twitter posts automatically when the scheduled runner executes. <br>\nMitigation: Use dry-run first and review scheduled and backlog files carefully before enabling cron. <br>\nRisk: Credential handling includes environment variables and a macOS Keychain fallback. <br>\nMitigation: Set X API credentials explicitly with environment variables and review the Keychain fallback before relying on it. <br>\nRisk: With deleteAfterPost enabled, posted queue files are removed after successful posting. <br>\nMitigation: Keep backups of queued content before enabling automatic posting or deletion. <br>\n\n\n## Reference(s): <br>\n- [ClawHub skill page](https://clawhub.ai/meimakes/xqueue) <br>\n- [Publisher profile](https://clawhub.ai/user/meimakes) <br>\n- [X API domain](https://api.x.com) <br>\n- [X media upload domain](https://upload.twitter.com) <br>\n\n\n## Skill Output: <br>\n**Output Type(s):** [Shell commands, Configuration, Files, Guidance] <br>\n**Output Format:** [Markdown guidance with shell commands and JSON configuration examples] <br>\n**Output Parameters:** [1D] <br>\n**Other Properties Related to Output:** [Creates and uses local queue folders, configuration files, post logs, and scheduled X/Twitter API calls.] <br>\n\n## Skill Version(s): <br>\n1.0.5 (source: server release evidence) <br>\n\n## Ethical Considerations: <br>\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment. <br>\n\nArchive v1.0.4: 5 files, 12479 bytes\n\nFiles: README.md (2473b), SKILL.md (6089b), xqueue-post.py (16512b), xqueue-setup.py (6007b), _meta.json (125b)\n\nFile v1.0.4:SKILL.md\n\n---\nname: xqueue\ndescription: File-based X/Twitter post scheduler. Drop tweets into day/time folders, they post automatically. No frontend, no app — your file system is the UI.\nmetadata: {\"openclaw\":{\"requires\":{\"env\":[\"X_CONSUMER_KEY\",\"X_CONSUMER_SECRET\",\"X_ACCESS_TOKEN\",\"X_ACCESS_TOKEN_SECRET\"],\"bins\":[\"python3\"],\"pip\":[\"requests\",\"requests-oauthlib\"]},\"permissions\":{\"filesystem\":\"read/write within xqueue/ directory, ~/.openclaw/workspace/xqueue/notifications.log\",\"network\":\"api.x.com, upload.twitter.com\",\"keychain\":\"macOS Keychain for X API credentials (fallback when env vars not set)\",\"system\":\"openclaw CLI wake command for notifications (best-effort, non-critical)\"}}}\n---\n\n# XQueue\n\nA file-based post scheduler for X (Twitter). Your file system is the UI.\n\n## How It Works\n\nCreate a folder structure with days and times. Drop tweet files into the time slots. A cron job checks every 15 minutes — if it's the right day and time and there's content, it posts and cleans up.\n\n```\nxqueue/\n  config.json\n  backlog/\n    ebook-launch-thread.md\n    ai-tools-roundup.md\n  Sunday/\n    10am/\n      my-tweet.md\n      photo.jpg\n  Monday/\n    9am/\n      thread-about-shipping.md\n    12pm/\n    5pm/\n  Tuesday/\n    ...\n```\n\nThe schedule cycles weekly. Monday's 9am slot fires every Monday at 9am. If the folder is empty, it pulls the oldest file from `backlog/` (sorted alphabetically). If there's content in the slot, it posts that and backlog waits. This means you can schedule up to a week of specific content, and dump everything else in backlog — it'll fill empty slots automatically.\n\nAfter posting, files are deleted (by default) so they don't repeat.\n\n## Setup\n\nRun the setup command to create your queue:\n\n```bash\npython3 xqueue-setup.py\n```\n\nThis asks you:\n1. How many times per day do you want to post?\n2. What times? (or let it pick optimal times)\n3. What timezone?\n4. Any X communities to post to?\n5. Thread separator preference (default: ---)\n6. Delete after posting? (recommended yes — if off, posts may send twice)\n\nCreates the full folder structure + config.json.\n\n## Tweet Format\n\n### Simple tweet\nJust write the text in a `.md` or `.txt` file:\n\n```\nThis is my tweet. It can be up to 280 characters.\n```\n\n### Tweet with community\nStart with `Post to [community name]:` on the first line:\n\n```\nPost to Build in Public: Just shipped my first ClawHub skill. File-based tweet scheduler, no frontend needed.\n```\n\n### Thread\nOne file, tweets separated by your configured separator (default `---`):\n\n```\nI built a file-based tweet scheduler with no frontend. Your filesystem is the UI.\n---\nDrop a .md file into Monday/9am/ and a cron job posts it. Empty slot? It pulls from a backlog/ folder automatically.\n---\nNo database, no app, no dashboard. Just folders and text files. Sometimes the simplest architecture wins.\n```\n\n### Tweet with media\nPut image/video files in the same time folder as the tweet. Supported: JPG, PNG, GIF (under 5MB for images, 15MB for GIF).\n\n```\n9am/\n  tweet.md        ← the text\n  progress.png    ← gets attached\n```\n\nIf multiple media files exist, they attach in alphabetical order (max 4 per tweet).\n\n## Config\n\n`xqueue/config.json`:\n\n```json\n{\n  \"timezone\": \"America/Chicago\",\n  \"separator\": \"---\",\n  \"deleteAfterPost\": true,\n  \"communities\": {\n    \"Build in Public\": \"community_id\",\n    \"Indie Hackers\": \"community_id\"\n  },\n  \"logFile\": \"xqueue/posted.log\",\n  \"dryRun\": false\n}\n```\n\nDuring setup, paste the community URL (like `x.com/i/communities/123456`) or the numeric ID directly. The script extracts the ID and asks for a display name. Plain names without an ID are rejected — everything needed to post is captured upfront.\n\n## Backlog\n\nThe `xqueue/backlog/` folder holds tweets that aren't scheduled for a specific slot. When the cron fires and a time slot is empty, it pulls the oldest file from backlog (alphabetical sort — prefix with numbers like `01-`, `02-` to control order).\n\nThis lets you batch-write content without worrying about fitting it into exactly the right number of weekly slots. Schedule what's time-sensitive, backlog the rest.\n\n## Cron Integration\n\nThe skill includes a cron job that runs every 15 minutes:\n- Checks current day + time against folder structure\n- If slot has content → post it\n- If slot is empty → pull oldest from `backlog/`\n- If both are empty → skip\n- Logs results to posted.log\n- Deletes posted files (if deleteAfterPost is on)\n\n## What Goes Where\n\n| You want to...                        | Do this                                               |\n| ------------------------------------- | ----------------------------------------------------- |\n| Schedule a tweet for Tuesday 9am      | Drop a .md file in `xqueue/Tuesday/9am/`              |\n| Post a thread                         | One .md file with `---` between tweets                |\n| Attach an image                       | Put the image file in the same folder as the .md file |\n| Post to a community                   | Start text with `Post to Community Name:`             |\n| Reorder posts                         | Move files between time folders                       |\n| Skip a time slot                      | Leave the folder empty                                |\n| See what's queued                     | Browse the xqueue folder                              |\n| See what already posted               | Check xqueue/posted.log                               |\n| Queue content without a specific time | Drop it in `xqueue/backlog/`                          |\n| Control backlog order                 | Prefix filenames: `01-first.md`, `02-second.md`       |\n\n## Important\n\n- **deleteAfterPost: true** (default) means each file posts once then gets removed. If you turn this off, the same content will post again next week when the cycle repeats.\n- Tweets over 280 characters are rejected (logged as error, not posted).\n- Thread tweets are each checked for 280 char limit individually.\n- Empty folders are silently skipped.\n- The cron checks every 15 minutes, so posts go out within 0-15 min of the scheduled time.\n\nFile v1.0.4:README.md\n\n# XQueue\n\nA file-based post scheduler for X (Twitter). Your file system is the UI.\n\nNo database. No dashboard. No app. Just folders, text files, and a cron job.\n\n## How It Works\n\n```\nxqueue/\n  config.json\n  backlog/\n  Monday/\n    9am/\n      thread-about-shipping.md\n    12pm/\n    5pm/\n  Tuesday/\n    ...\n```\n\n- **Drop a `.md` file into a day/time folder** → it posts at that time\n- **Empty slot?** → pulls the oldest file from `backlog/` automatically\n- **Schedule cycles weekly** → Monday/9am fires every Monday at 9am\n- **Files are deleted after posting** (configurable) so nothing repeats\n\n## Setup\n\n```bash\npython3 xqueue-setup.py\n```\n\nThe setup wizard asks how many daily posts, what times, timezone, and optional X community targets (paste the community URL, it extracts the ID). Creates the full folder structure + `config.json`.\n\n## Tweet Formats\n\n**Simple tweet** — just text in a `.md` file:\n```\nJust shipped v2. Sometimes the simplest architecture wins.\n```\n\n**Thread** — one file, `---` between tweets:\n```\nI built a file-based tweet scheduler with no frontend. Your filesystem is the UI.\n---\nDrop a .md file into Monday/9am/ and a cron job posts it. Empty slot? It pulls from backlog automatically.\n---\nNo database, no app, no dashboard. Just folders and text files.\n```\n\n**With media** — put images in the same folder (max 4, alphabetical order):\n```\n9am/\n  tweet.md\n  screenshot.png\n```\n\n**Community post** — prefix with the community name:\n```\nPost to Build in Public: Just shipped my first skill. File-based tweet scheduler, no frontend needed.\n```\n\n## Backlog\n\nThe `backlog/` folder holds content without a specific time slot. When a scheduled slot is empty, the oldest backlog file gets posted. Prefix filenames with numbers (`01-`, `02-`) to control order.\n\nWrite a week of content in one sitting, dump it in backlog, and it distributes itself across your empty slots.\n\n## Cron\n\nDesigned to run on a 15-minute cron cycle. Each tick:\n1. Checks current day + time against folder structure\n2. Posts slot content (or pulls from backlog if empty)\n3. Logs to `posted.log`\n4. Cleans up posted files\n\n## Requirements\n\n- Python 3\n- X API credentials via environment variables:\n  - `X_CONSUMER_KEY`, `X_CONSUMER_SECRET` (app credentials)\n  - `X_ACCESS_TOKEN`, `X_ACCESS_TOKEN_SECRET` (user credentials)\n  - Optional: set `XQUEUE_KEYCHAIN_ACCOUNT` to use macOS Keychain as fallback\n- A cron runner (OpenClaw cron, system cron, etc.)\n\n## License\n\nMIT\n\nFile v1.0.4:_meta.json\n\n{\n  \"ownerId\": \"kn711gxkbyw34qye3faaqw24yn8163fm\",\n  \"slug\": \"xqueue\",\n  \"version\": \"1.0.4\",\n  \"publishedAt\": 1774371492602\n}\n\nArchive v1.0.3: 5 files, 12407 bytes\n\nFiles: README.md (2473b), SKILL.md (5946b), xqueue-post.py (16512b), xqueue-setup.py (6007b), _meta.json (125b)\n\nFile v1.0.3:SKILL.md\n\n---\nname: xqueue\ndescription: File-based X/Twitter post scheduler. Drop tweets into day/time folders, they post automatically. No frontend, no app — your file system is the UI.\nmetadata: {\"openclaw\":{\"requires\":{\"env\":[\"X_CONSUMER_KEY\",\"X_CONSUMER_SECRET\",\"X_ACCESS_TOKEN\",\"X_ACCESS_TOKEN_SECRET\"],\"bins\":[\"python3\"],\"pip\":[\"requests\",\"requests-oauthlib\"]},\"permissions\":{\"filesystem\":\"read/write within xqueue/ directory\",\"network\":\"api.x.com, upload.twitter.com\",\"keychain\":\"optional macOS Keychain if XQUEUE_KEYCHAIN_ACCOUNT is set\"}}}\n---\n\n# XQueue\n\nA file-based post scheduler for X (Twitter). Your file system is the UI.\n\n## How It Works\n\nCreate a folder structure with days and times. Drop tweet files into the time slots. A cron job checks every 15 minutes — if it's the right day and time and there's content, it posts and cleans up.\n\n```\nxqueue/\n  config.json\n  backlog/\n    ebook-launch-thread.md\n    ai-tools-roundup.md\n  Sunday/\n    10am/\n      my-tweet.md\n      photo.jpg\n  Monday/\n    9am/\n      thread-about-shipping.md\n    12pm/\n    5pm/\n  Tuesday/\n    ...\n```\n\nThe schedule cycles weekly. Monday's 9am slot fires every Monday at 9am. If the folder is empty, it pulls the oldest file from `backlog/` (sorted alphabetically). If there's content in the slot, it posts that and backlog waits. This means you can schedule up to a week of specific content, and dump everything else in backlog — it'll fill empty slots automatically.\n\nAfter posting, files are deleted (by default) so they don't repeat.\n\n## Setup\n\nRun the setup command to create your queue:\n\n```bash\npython3 xqueue-setup.py\n```\n\nThis asks you:\n1. How many times per day do you want to post?\n2. What times? (or let it pick optimal times)\n3. What timezone?\n4. Any X communities to post to?\n5. Thread separator preference (default: ---)\n6. Delete after posting? (recommended yes — if off, posts may send twice)\n\nCreates the full folder structure + config.json.\n\n## Tweet Format\n\n### Simple tweet\nJust write the text in a `.md` or `.txt` file:\n\n```\nThis is my tweet. It can be up to 280 characters.\n```\n\n### Tweet with community\nStart with `Post to [community name]:` on the first line:\n\n```\nPost to Build in Public: Just shipped my first ClawHub skill. File-based tweet scheduler, no frontend needed.\n```\n\n### Thread\nOne file, tweets separated by your configured separator (default `---`):\n\n```\nI built a file-based tweet scheduler with no frontend. Your filesystem is the UI.\n---\nDrop a .md file into Monday/9am/ and a cron job posts it. Empty slot? It pulls from a backlog/ folder automatically.\n---\nNo database, no app, no dashboard. Just folders and text files. Sometimes the simplest architecture wins.\n```\n\n### Tweet with media\nPut image/video files in the same time folder as the tweet. Supported: JPG, PNG, GIF (under 5MB for images, 15MB for GIF).\n\n```\n9am/\n  tweet.md        ← the text\n  progress.png    ← gets attached\n```\n\nIf multiple media files exist, they attach in alphabetical order (max 4 per tweet).\n\n## Config\n\n`xqueue/config.json`:\n\n```json\n{\n  \"timezone\": \"America/Chicago\",\n  \"separator\": \"---\",\n  \"deleteAfterPost\": true,\n  \"communities\": {\n    \"Build in Public\": \"community_id\",\n    \"Indie Hackers\": \"community_id\"\n  },\n  \"logFile\": \"xqueue/posted.log\",\n  \"dryRun\": false\n}\n```\n\nDuring setup, paste the community URL (like `x.com/i/communities/123456`) or the numeric ID directly. The script extracts the ID and asks for a display name. Plain names without an ID are rejected — everything needed to post is captured upfront.\n\n## Backlog\n\nThe `xqueue/backlog/` folder holds tweets that aren't scheduled for a specific slot. When the cron fires and a time slot is empty, it pulls the oldest file from backlog (alphabetical sort — prefix with numbers like `01-`, `02-` to control order).\n\nThis lets you batch-write content without worrying about fitting it into exactly the right number of weekly slots. Schedule what's time-sensitive, backlog the rest.\n\n## Cron Integration\n\nThe skill includes a cron job that runs every 15 minutes:\n- Checks current day + time against folder structure\n- If slot has content → post it\n- If slot is empty → pull oldest from `backlog/`\n- If both are empty → skip\n- Logs results to posted.log\n- Deletes posted files (if deleteAfterPost is on)\n\n## What Goes Where\n\n| You want to...                        | Do this                                               |\n| ------------------------------------- | ----------------------------------------------------- |\n| Schedule a tweet for Tuesday 9am      | Drop a .md file in `xqueue/Tuesday/9am/`              |\n| Post a thread                         | One .md file with `---` between tweets                |\n| Attach an image                       | Put the image file in the same folder as the .md file |\n| Post to a community                   | Start text with `Post to Community Name:`             |\n| Reorder posts                         | Move files between time folders                       |\n| Skip a time slot                      | Leave the folder empty                                |\n| See what's queued                     | Browse the xqueue folder                              |\n| See what already posted               | Check xqueue/posted.log                               |\n| Queue content without a specific time | Drop it in `xqueue/backlog/`                          |\n| Control backlog order                 | Prefix filenames: `01-first.md`, `02-second.md`       |\n\n## Important\n\n- **deleteAfterPost: true** (default) means each file posts once then gets removed. If you turn this off, the same content will post again next week when the cycle repeats.\n- Tweets over 280 characters are rejected (logged as error, not posted).\n- Thread tweets are each checked for 280 char limit individually.\n- Empty folders are silently skipped.\n- The cron checks every 15 minutes, so posts go out within 0-15 min of the scheduled time.\n\nFile v1.0.3:README.md\n\n# XQueue\n\nA file-based post scheduler for X (Twitter). Your file system is the UI.\n\nNo database. No dashboard. No app. Just folders, text files, and a cron job.\n\n## How It Works\n\n```\nxqueue/\n  config.json\n  backlog/\n  Monday/\n    9am/\n      thread-about-shipping.md\n    12pm/\n    5pm/\n  Tuesday/\n    ...\n```\n\n- **Drop a `.md` file into a day/time folder** → it posts at that time\n- **Empty slot?** → pulls the oldest file from `backlog/` automatically\n- **Schedule cycles weekly** → Monday/9am fires every Monday at 9am\n- **Files are deleted after posting** (configurable) so nothing repeats\n\n## Setup\n\n```bash\npython3 xqueue-setup.py\n```\n\nThe setup wizard asks how many daily posts, what times, timezone, and optional X community targets (paste the community URL, it extracts the ID). Creates the full folder structure + `config.json`.\n\n## Tweet Formats\n\n**Simple tweet** — just text in a `.md` file:\n```\nJust shipped v2. Sometimes the simplest architecture wins.\n```\n\n**Thread** — one file, `---` between tweets:\n```\nI built a file-based tweet scheduler with no frontend. Your filesystem is the UI.\n---\nDrop a .md file into Monday/9am/ and a cron job posts it. Empty slot? It pulls from backlog automatically.\n---\nNo database, no app, no dashboard. Just folders and text files.\n```\n\n**With media** — put images in the same folder (max 4, alphabetical order):\n```\n9am/\n  tweet.md\n  screenshot.png\n```\n\n**Community post** — prefix with the community name:\n```\nPost to Build in Public: Just shipped my first skill. File-based tweet scheduler, no frontend needed.\n```\n\n## Backlog\n\nThe `backlog/` folder holds content without a specific time slot. When a scheduled slot is empty, the oldest backlog file gets posted. Prefix filenames with numbers (`01-`, `02-`) to control order.\n\nWrite a week of content in one sitting, dump it in backlog, and it distributes itself across your empty slots.\n\n## Cron\n\nDesigned to run on a 15-minute cron cycle. Each tick:\n1. Checks current day + time against folder structure\n2. Posts slot content (or pulls from backlog if empty)\n3. Logs to `posted.log`\n4. Cleans up posted files\n\n## Requirements\n\n- Python 3\n- X API credentials via environment variables:\n  - `X_CONSUMER_KEY`, `X_CONSUMER_SECRET` (app credentials)\n  - `X_ACCESS_TOKEN`, `X_ACCESS_TOKEN_SECRET` (user credentials)\n  - Optional: set `XQUEUE_KEYCHAIN_ACCOUNT` to use macOS Keychain as fallback\n- A cron runner (OpenClaw cron, system cron, etc.)\n\n## License\n\nMIT\n\nFile v1.0.3:_meta.json\n\n{\n  \"ownerId\": \"kn711gxkbyw34qye3faaqw24yn8163fm\",\n  \"slug\": \"xqueue\",\n  \"version\": \"1.0.3\",\n  \"publishedAt\": 1774366359105\n}\n\nArchive v1.0.2: 5 files, 11658 bytes\n\nFiles: README.md (2473b), SKILL.md (5913b), xqueue-post.py (15318b), xqueue-setup.py (5469b), _meta.json (125b)\n\nFile v1.0.2:SKILL.md\n\n---\nname: xqueue\ndescription: File-based X/Twitter post scheduler. Drop tweets into day/time folders, they post automatically. No frontend, no app — your file system is the UI.\nmetadata: {\"openclaw\":{\"requires\":{\"env\":[\"X_CONSUMER_KEY\",\"X_CONSUMER_SECRET\",\"X_ACCESS_TOKEN\",\"X_ACCESS_TOKEN_SECRET\"],\"bins\":[\"python3\"]},\"permissions\":{\"filesystem\":\"read/write within xqueue/ directory\",\"network\":\"api.twitter.com, upload.twitter.com\",\"keychain\":\"optional macOS Keychain if XQUEUE_KEYCHAIN_ACCOUNT is set\"}}}\n---\n\n# XQueue\n\nA file-based post scheduler for X (Twitter). Your file system is the UI.\n\n## How It Works\n\nCreate a folder structure with days and times. Drop tweet files into the time slots. A cron job checks every 15 minutes — if it's the right day and time and there's content, it posts and cleans up.\n\n```\nxqueue/\n  config.json\n  backlog/\n    ebook-launch-thread.md\n    ai-tools-roundup.md\n  Sunday/\n    10am/\n      my-tweet.md\n      photo.jpg\n  Monday/\n    9am/\n      thread-about-shipping.md\n    12pm/\n    5pm/\n  Tuesday/\n    ...\n```\n\nThe schedule cycles weekly. Monday's 9am slot fires every Monday at 9am. If the folder is empty, it pulls the oldest file from `backlog/` (sorted alphabetically). If there's content in the slot, it posts that and backlog waits. This means you can schedule up to a week of specific content, and dump everything else in backlog — it'll fill empty slots automatically.\n\nAfter posting, files are deleted (by default) so they don't repeat.\n\n## Setup\n\nRun the setup command to create your queue:\n\n```bash\npython3 xqueue-setup.py\n```\n\nThis asks you:\n1. How many times per day do you want to post?\n2. What times? (or let it pick optimal times)\n3. What timezone?\n4. Any X communities to post to?\n5. Thread separator preference (default: ---)\n6. Delete after posting? (recommended yes — if off, posts may send twice)\n\nCreates the full folder structure + config.json.\n\n## Tweet Format\n\n### Simple tweet\nJust write the text in a `.md` or `.txt` file:\n\n```\nThis is my tweet. It can be up to 280 characters.\n```\n\n### Tweet with community\nStart with `Post to [community name]:` on the first line:\n\n```\nPost to Build in Public: Just shipped my first ClawHub skill. File-based tweet scheduler, no frontend needed.\n```\n\n### Thread\nOne file, tweets separated by your configured separator (default `---`):\n\n```\nI built a file-based tweet scheduler with no frontend. Your filesystem is the UI.\n---\nDrop a .md file into Monday/9am/ and a cron job posts it. Empty slot? It pulls from a backlog/ folder automatically.\n---\nNo database, no app, no dashboard. Just folders and text files. Sometimes the simplest architecture wins.\n```\n\n### Tweet with media\nPut image/video files in the same time folder as the tweet. Supported: JPG, PNG, GIF (under 5MB for images, 15MB for GIF).\n\n```\n9am/\n  tweet.md        ← the text\n  progress.png    ← gets attached\n```\n\nIf multiple media files exist, they attach in alphabetical order (max 4 per tweet).\n\n## Config\n\n`xqueue/config.json`:\n\n```json\n{\n  \"timezone\": \"America/Chicago\",\n  \"separator\": \"---\",\n  \"deleteAfterPost\": true,\n  \"communities\": {\n    \"Build in Public\": \"community_id\",\n    \"Indie Hackers\": \"community_id\"\n  },\n  \"logFile\": \"xqueue/posted.log\",\n  \"dryRun\": false\n}\n```\n\nDuring setup, paste the community URL (like `x.com/i/communities/123456`) or the numeric ID directly. The script extracts the ID and asks for a display name. Plain names without an ID are rejected — everything needed to post is captured upfront.\n\n## Backlog\n\nThe `xqueue/backlog/` folder holds tweets that aren't scheduled for a specific slot. When the cron fires and a time slot is empty, it pulls the oldest file from backlog (alphabetical sort — prefix with numbers like `01-`, `02-` to control order).\n\nThis lets you batch-write content without worrying about fitting it into exactly the right number of weekly slots. Schedule what's time-sensitive, backlog the rest.\n\n## Cron Integration\n\nThe skill includes a cron job that runs every 15 minutes:\n- Checks current day + time against folder structure\n- If slot has content → post it\n- If slot is empty → pull oldest from `backlog/`\n- If both are empty → skip\n- Logs results to posted.log\n- Deletes posted files (if deleteAfterPost is on)\n\n## What Goes Where\n\n| You want to...                        | Do this                                               |\n| ------------------------------------- | ----------------------------------------------------- |\n| Schedule a tweet for Tuesday 9am      | Drop a .md file in `xqueue/Tuesday/9am/`              |\n| Post a thread                         | One .md file with `---` between tweets                |\n| Attach an image                       | Put the image file in the same folder as the .md file |\n| Post to a community                   | Start text with `Post to Community Name:`             |\n| Reorder posts                         | Move files between time folders                       |\n| Skip a time slot                      | Leave the folder empty                                |\n| See what's queued                     | Browse the xqueue folder                              |\n| See what already posted               | Check xqueue/posted.log                               |\n| Queue content without a specific time | Drop it in `xqueue/backlog/`                          |\n| Control backlog order                 | Prefix filenames: `01-first.md`, `02-second.md`       |\n\n## Important\n\n- **deleteAfterPost: true** (default) means each file posts once then gets removed. If you turn this off, the same content will post again next week when the cycle repeats.\n- Tweets over 280 characters are rejected (logged as error, not posted).\n- Thread tweets are each checked for 280 char limit individually.\n- Empty folders are silently skipped.\n- The cron checks every 15 minutes, so posts go out within 0-15 min of the scheduled time.\n\nFile v1.0.2:README.md\n\n# XQueue\n\nA file-based post scheduler for X (Twitter). Your file system is the UI.\n\nNo database. No dashboard. No app. Just folders, text files, and a cron job.\n\n## How It Works\n\n```\nxqueue/\n  config.json\n  backlog/\n  Monday/\n    9am/\n      thread-about-shipping.md\n    12pm/\n    5pm/\n  Tuesday/\n    ...\n```\n\n- **Drop a `.md` file into a day/time folder** → it posts at that time\n- **Empty slot?** → pulls the oldest file from `backlog/` automatically\n- **Schedule cycles weekly** → Monday/9am fires every Monday at 9am\n- **Files are deleted after posting** (configurable) so nothing repeats\n\n## Setup\n\n```bash\npython3 xqueue-setup.py\n```\n\nThe setup wizard asks how many daily posts, what times, timezone, and optional X community targets (paste the community URL, it extracts the ID). Creates the full folder structure + `config.json`.\n\n## Tweet Formats\n\n**Simple tweet** — just text in a `.md` file:\n```\nJust shipped v2. Sometimes the simplest architecture wins.\n```\n\n**Thread** — one file, `---` between tweets:\n```\nI built a file-based tweet scheduler with no frontend. Your filesystem is the UI.\n---\nDrop a .md file into Monday/9am/ and a cron job posts it. Empty slot? It pulls from backlog automatically.\n---\nNo database, no app, no dashboard. Just folders and text files.\n```\n\n**With media** — put images in the same folder (max 4, alphabetical order):\n```\n9am/\n  tweet.md\n  screenshot.png\n```\n\n**Community post** — prefix with the community name:\n```\nPost to Build in Public: Just shipped my first skill. File-based tweet scheduler, no frontend needed.\n```\n\n## Backlog\n\nThe `backlog/` folder holds content without a specific time slot. When a scheduled slot is empty, the oldest backlog file gets posted. Prefix filenames with numbers (`01-`, `02-`) to control order.\n\nWrite a week of content in one sitting, dump it in backlog, and it distributes itself across your empty slots.\n\n## Cron\n\nDesigned to run on a 15-minute cron cycle. Each tick:\n1. Checks current day + time against folder structure\n2. Posts slot content (or pulls from backlog if empty)\n3. Logs to `posted.log`\n4. Cleans up posted files\n\n## Requirements\n\n- Python 3\n- X API credentials via environment variables:\n  - `X_CONSUMER_KEY`, `X_CONSUMER_SECRET` (app credentials)\n  - `X_ACCESS_TOKEN`, `X_ACCESS_TOKEN_SECRET` (user credentials)\n  - Optional: set `XQUEUE_KEYCHAIN_ACCOUNT` to use macOS Keychain as fallback\n- A cron runner (OpenClaw cron, system cron, etc.)\n\n## License\n\nMIT\n\nFile v1.0.2:_meta.json\n\n{\n  \"ownerId\": \"kn711gxkbyw34qye3faaqw24yn8163fm\",\n  \"slug\": \"xqueue\",\n  \"version\": \"1.0.2\",\n  \"publishedAt\": 1771958168123\n}\n\nArchive v1.0.1: 5 files, 11671 bytes\n\nFiles: README.md (2473b), SKILL.md (5983b), xqueue-post.py (15318b), xqueue-setup.py (5469b), _meta.json (125b)\n\nFile v1.0.1:SKILL.md\n\n---\nname: xqueue\ndescription: File-based X/Twitter post scheduler. Drop tweets into day/time folders, they post automatically. No frontend, no app — your file system is the UI.\nrequires:\n  env:\n    - X_CONSUMER_KEY\n    - X_CONSUMER_SECRET\n    - X_ACCESS_TOKEN\n    - X_ACCESS_TOKEN_SECRET\n  runtime: python3\npermissions:\n  filesystem: read/write within xqueue/ directory (config, logs, tweet files)\n  network: api.twitter.com, upload.twitter.com (posting tweets and media)\n  keychain: optional macOS Keychain access if XQUEUE_KEYCHAIN_ACCOUNT is set (fallback for credentials)\n---\n\n# XQueue\n\nA file-based post scheduler for X (Twitter). Your file system is the UI.\n\n## How It Works\n\nCreate a folder structure with days and times. Drop tweet files into the time slots. A cron job checks every 15 minutes — if it's the right day and time and there's content, it posts and cleans up.\n\n```\nxqueue/\n  config.json\n  backlog/\n    ebook-launch-thread.md\n    ai-tools-roundup.md\n  Sunday/\n    10am/\n      my-tweet.md\n      photo.jpg\n  Monday/\n    9am/\n      thread-about-shipping.md\n    12pm/\n    5pm/\n  Tuesday/\n    ...\n```\n\nThe schedule cycles weekly. Monday's 9am slot fires every Monday at 9am. If the folder is empty, it pulls the oldest file from `backlog/` (sorted alphabetically). If there's content in the slot, it posts that and backlog waits. This means you can schedule up to a week of specific content, and dump everything else in backlog — it'll fill empty slots automatically.\n\nAfter posting, files are deleted (by default) so they don't repeat.\n\n## Setup\n\nRun the setup command to create your queue:\n\n```bash\npython3 xqueue-setup.py\n```\n\nThis asks you:\n1. How many times per day do you want to post?\n2. What times? (or let it pick optimal times)\n3. What timezone?\n4. Any X communities to post to?\n5. Thread separator preference (default: ---)\n6. Delete after posting? (recommended yes — if off, posts may send twice)\n\nCreates the full folder structure + config.json.\n\n## Tweet Format\n\n### Simple tweet\nJust write the text in a `.md` or `.txt` file:\n\n```\nThis is my tweet. It can be up to 280 characters.\n```\n\n### Tweet with community\nStart with `Post to [community name]:` on the first line:\n\n```\nPost to Build in Public: Just shipped my first ClawHub skill. File-based tweet scheduler, no frontend needed.\n```\n\n### Thread\nOne file, tweets separated by your configured separator (default `---`):\n\n```\nI built a file-based tweet scheduler with no frontend. Your filesystem is the UI.\n---\nDrop a .md file into Monday/9am/ and a cron job posts it. Empty slot? It pulls from a backlog/ folder automatically.\n---\nNo database, no app, no dashboard. Just folders and text files. Sometimes the simplest architecture wins.\n```\n\n### Tweet with media\nPut image/video files in the same time folder as the tweet. Supported: JPG, PNG, GIF (under 5MB for images, 15MB for GIF).\n\n```\n9am/\n  tweet.md        ← the text\n  progress.png    ← gets attached\n```\n\nIf multiple media files exist, they attach in alphabetical order (max 4 per tweet).\n\n## Config\n\n`xqueue/config.json`:\n\n```json\n{\n  \"timezone\": \"America/Chicago\",\n  \"separator\": \"---\",\n  \"deleteAfterPost\": true,\n  \"communities\": {\n    \"Build in Public\": \"community_id\",\n    \"Indie Hackers\": \"community_id\"\n  },\n  \"logFile\": \"xqueue/posted.log\",\n  \"dryRun\": false\n}\n```\n\nDuring setup, paste the community URL (like `x.com/i/communities/123456`) or the numeric ID directly. The script extracts the ID and asks for a display name. Plain names without an ID are rejected — everything needed to post is captured upfront.\n\n## Backlog\n\nThe `xqueue/backlog/` folder holds tweets that aren't scheduled for a specific slot. When the cron fires and a time slot is empty, it pulls the oldest file from backlog (alphabetical sort — prefix with numbers like `01-`, `02-` to control order).\n\nThis lets you batch-write content without worrying about fitting it into exactly the right number of weekly slots. Schedule what's time-sensitive, backlog the rest.\n\n## Cron Integration\n\nThe skill includes a cron job that runs every 15 minutes:\n- Checks current day + time against folder structure\n- If slot has content → post it\n- If slot is empty → pull oldest from `backlog/`\n- If both are empty → skip\n- Logs results to posted.log\n- Deletes posted files (if deleteAfterPost is on)\n\n## What Goes Where\n\n| You want to...                        | Do this                                               |\n| ------------------------------------- | ----------------------------------------------------- |\n| Schedule a tweet for Tuesday 9am      | Drop a .md file in `xqueue/Tuesday/9am/`              |\n| Post a thread                         | One .md file with `---` between tweets                |\n| Attach an image                       | Put the image file in the same folder as the .md file |\n| Post to a community                   | Start text with `Post to Community Name:`             |\n| Reorder posts                         | Move files between time folders                       |\n| Skip a time slot                      | Leave the folder empty                                |\n| See what's queued                     | Browse the xqueue folder                              |\n| See what already posted               | Check xqueue/posted.log                               |\n| Queue content without a specific time | Drop it in `xqueue/backlog/`                          |\n| Control backlog order                 | Prefix filenames: `01-first.md`, `02-second.md`       |\n\n## Important\n\n- **deleteAfterPost: true** (default) means each file posts once then gets removed. If you turn this off, the same content will post again next week when the cycle repeats.\n- Tweets over 280 characters are rejected (logged as error, not posted).\n- Thread tweets are each checked for 280 char limit individually.\n- Empty folders are silently skipped.\n- The cron checks every 15 minutes, so posts go out within 0-15 min of the scheduled time.\n\nFile v1.0.1:README.md\n\n# XQueue\n\nA file-based post scheduler for X (Twitter). Your file system is the UI.\n\nNo database. No dashboard. No app. Just folders, text files, and a cron job.\n\n## How It Works\n\n```\nxqueue/\n  config.json\n  backlog/\n  Monday/\n    9am/\n      thread-about-shipping.md\n    12pm/\n    5pm/\n  Tuesday/\n    ...\n```\n\n- **Drop a `.md` file into a day/time folder** → it posts at that time\n- **Empty slot?** → pulls the oldest file from `backlog/` automatically\n- **Schedule cycles weekly** → Monday/9am fires every Monday at 9am\n- **Files are deleted after posting** (configurable) so nothing repeats\n\n## Setup\n\n```bash\npython3 xqueue-setup.py\n```\n\nThe setup wizard asks how many daily posts, what times, timezone, and optional X community targets (paste the community URL, it extracts the ID). Creates the full folder structure + `config.json`.\n\n## Tweet Formats\n\n**Simple tweet** — just text in a `.md` file:\n```\nJust shipped v2. Sometimes the simplest architecture wins.\n```\n\n**Thread** — one file, `---` between tweets:\n```\nI built a file-based tweet scheduler with no frontend. Your filesystem is the UI.\n---\nDrop a .md file into Monday/9am/ and a cron job posts it. Empty slot? It pulls from backlog automatically.\n---\nNo database, no app, no dashboard. Just folders and text files.\n```\n\n**With media** — put images in the same folder (max 4, alphabetical order):\n```\n9am/\n  tweet.md\n  screenshot.png\n```\n\n**Community post** — prefix with the community name:\n```\nPost to Build in Public: Just shipped my first skill. File-based tweet scheduler, no frontend needed.\n```\n\n## Backlog\n\nThe `backlog/` folder holds content without a specific time slot. When a scheduled slot is empty, the oldest backlog file gets posted. Prefix filenames with numbers (`01-`, `02-`) to control order.\n\nWrite a week of content in one sitting, dump it in backlog, and it distributes itself across your empty slots.\n\n## Cron\n\nDesigned to run on a 15-minute cron cycle. Each tick:\n1. Checks current day + time against folder structure\n2. Posts slot content (or pulls from backlog if empty)\n3. Logs to `posted.log`\n4. Cleans up posted files\n\n## Requirements\n\n- Python 3\n- X API credentials via environment variables:\n  - `X_CONSUMER_KEY`, `X_CONSUMER_SECRET` (app credentials)\n  - `X_ACCESS_TOKEN`, `X_ACCESS_TOKEN_SECRET` (user credentials)\n  - Optional: set `XQUEUE_KEYCHAIN_ACCOUNT` to use macOS Keychain as fallback\n- A cron runner (OpenClaw cron, system cron, etc.)\n\n## License\n\nMIT\n\nFile v1.0.1:_meta.json\n\n{\n  \"ownerId\": \"kn711gxkbyw34qye3faaqw24yn8163fm\",\n  \"slug\": \"xqueue\",\n  \"version\": \"1.0.1\",\n  \"publishedAt\": 1771871413148\n}\n\nArchive v1.0.0: 5 files, 11145 bytes\n\nFiles: README.md (2268b), SKILL.md (5584b), xqueue-post.py (14645b), xqueue-setup.py (5469b), _meta.json (125b)\n\nFile v1.0.0:SKILL.md\n\n---\nname: xqueue\ndescription: File-based X/Twitter post scheduler. Drop tweets into day/time folders, they post automatically. No frontend, no app — your file system is the UI.\n---\n\n# XQueue\n\nA file-based post scheduler for X (Twitter). Your file system is the UI.\n\n## How It Works\n\nCreate a folder structure with days and times. Drop tweet files into the time slots. A cron job checks every 15 minutes — if it's the right day and time and there's content, it posts and cleans up.\n\n```\nxqueue/\n  config.json\n  backlog/\n    ebook-launch-thread.md\n    ai-tools-roundup.md\n  Sunday/\n    10am/\n      my-tweet.md\n      photo.jpg\n  Monday/\n    9am/\n      thread-about-shipping.md\n    12pm/\n    5pm/\n  Tuesday/\n    ...\n```\n\nThe schedule cycles weekly. Monday's 9am slot fires every Monday at 9am. If the folder is empty, it pulls the oldest file from `backlog/` (sorted alphabetically). If there's content in the slot, it posts that and backlog waits. This means you can schedule up to a week of specific content, and dump everything else in backlog — it'll fill empty slots automatically.\n\nAfter posting, files are deleted (by default) so they don't repeat.\n\n## Setup\n\nRun the setup command to create your queue:\n\n```bash\npython3 xqueue-setup.py\n```\n\nThis asks you:\n1. How many times per day do you want to post?\n2. What times? (or let it pick optimal times)\n3. What timezone?\n4. Any X communities to post to?\n5. Thread separator preference (default: ---)\n6. Delete after posting? (recommended yes — if off, posts may send twice)\n\nCreates the full folder structure + config.json.\n\n## Tweet Format\n\n### Simple tweet\nJust write the text in a `.md` or `.txt` file:\n\n```\nThis is my tweet. It can be up to 280 characters.\n```\n\n### Tweet with community\nStart with `Post to [community name]:` on the first line:\n\n```\nPost to Build in Public: Just shipped my first ClawHub skill. File-based tweet scheduler, no frontend needed.\n```\n\n### Thread\nOne file, tweets separated by your configured separator (default `---`):\n\n```\nI built a file-based tweet scheduler with no frontend. Your filesystem is the UI.\n---\nDrop a .md file into Monday/9am/ and a cron job posts it. Empty slot? It pulls from a backlog/ folder automatically.\n---\nNo database, no app, no dashboard. Just folders and text files. Sometimes the simplest architecture wins.\n```\n\n### Tweet with media\nPut image/video files in the same time folder as the tweet. Supported: JPG, PNG, GIF (under 5MB for images, 15MB for GIF).\n\n```\n9am/\n  tweet.md        ← the text\n  progress.png    ← gets attached\n```\n\nIf multiple media files exist, they attach in alphabetical order (max 4 per tweet).\n\n## Config\n\n`xqueue/config.json`:\n\n```json\n{\n  \"timezone\": \"America/Chicago\",\n  \"separator\": \"---\",\n  \"deleteAfterPost\": true,\n  \"communities\": {\n    \"Build in Public\": \"community_id\",\n    \"Indie Hackers\": \"community_id\"\n  },\n  \"logFile\": \"xqueue/posted.log\",\n  \"dryRun\": false\n}\n```\n\nDuring setup, paste the community URL (like `x.com/i/communities/123456`) or the numeric ID directly. The script extracts the ID and asks for a display name. Plain names without an ID are rejected — everything needed to post is captured upfront.\n\n## Backlog\n\nThe `xqueue/backlog/` folder holds tweets that aren't scheduled for a specific slot. When the cron fires and a time slot is empty, it pulls the oldest file from backlog (alphabetical sort — prefix with numbers like `01-`, `02-` to control order).\n\nThis lets you batch-write content without worrying about fitting it into exactly the right number of weekly slots. Schedule what's time-sensitive, backlog the rest.\n\n## Cron Integration\n\nThe skill includes a cron job that runs every 15 minutes:\n- Checks current day + time against folder structure\n- If slot has content → post it\n- If slot is empty → pull oldest from `backlog/`\n- If both are empty → skip\n- Logs results to posted.log\n- Deletes posted files (if deleteAfterPost is on)\n\n## What Goes Where\n\n| You want to...                        | Do this                                               |\n| ------------------------------------- | ----------------------------------------------------- |\n| Schedule a tweet for Tuesday 9am      | Drop a .md file in `xqueue/Tuesday/9am/`              |\n| Post a thread                         | One .md file with `---` between tweets                |\n| Attach an image                       | Put the image file in the same folder as the .md file |\n| Post to a community                   | Start text with `Post to Community Name:`             |\n| Reorder posts                         | Move files between time folders                       |\n| Skip a time slot                      | Leave the folder empty                                |\n| See what's queued                     | Browse the xqueue folder                              |\n| See what already posted               | Check xqueue/posted.log                               |\n| Queue content without a specific time | Drop it in `xqueue/backlog/`                          |\n| Control backlog order                 | Prefix filenames: `01-first.md`, `02-second.md`       |\n\n## Important\n\n- **deleteAfterPost: true** (default) means each file posts once then gets removed. If you turn this off, the same content will post again next week when the cycle repeats.\n- Tweets over 280 characters are rejected (logged as error, not posted).\n- Thread tweets are each checked for 280 char limit individually.\n- Empty folders are silently skipped.\n- The cron checks every 15 minutes, so posts go out within 0-15 min of the scheduled time.\n\nFile v1.0.0:README.md\n\n# XQueue\n\nA file-based post scheduler for X (Twitter). Your file system is the UI.\n\nNo database. No dashboard. No app. Just folders, text files, and a cron job.\n\n## How It Works\n\n```\nxqueue/\n  config.json\n  backlog/\n  Monday/\n    9am/\n      thread-about-shipping.md\n    12pm/\n    5pm/\n  Tuesday/\n    ...\n```\n\n- **Drop a `.md` file into a day/time folder** → it posts at that time\n- **Empty slot?** → pulls the oldest file from `backlog/` automatically\n- **Schedule cycles weekly** → Monday/9am fires every Monday at 9am\n- **Files are deleted after posting** (configurable) so nothing repeats\n\n## Setup\n\n```bash\npython3 xqueue-setup.py\n```\n\nThe setup wizard asks how many daily posts, what times, timezone, and optional X community targets (paste the community URL, it extracts the ID). Creates the full folder structure + `config.json`.\n\n## Tweet Formats\n\n**Simple tweet** — just text in a `.md` file:\n```\nJust shipped v2. Sometimes the simplest architecture wins.\n```\n\n**Thread** — one file, `---` between tweets:\n```\nI built a file-based tweet scheduler with no frontend. Your filesystem is the UI.\n---\nDrop a .md file into Monday/9am/ and a cron job posts it. Empty slot? It pulls from backlog automatically.\n---\nNo database, no app, no dashboard. Just folders and text files.\n```\n\n**With media** — put images in the same folder (max 4, alphabetical order):\n```\n9am/\n  tweet.md\n  screenshot.png\n```\n\n**Community post** — prefix with the community name:\n```\nPost to Build in Public: Just shipped my first skill. File-based tweet scheduler, no frontend needed.\n```\n\n## Backlog\n\nThe `backlog/` folder holds content without a specific time slot. When a scheduled slot is empty, the oldest backlog file gets posted. Prefix filenames with numbers (`01-`, `02-`) to control order.\n\nWrite a week of content in one sitting, dump it in backlog, and it distributes itself across your empty slots.\n\n## Cron\n\nDesigned to run on a 15-minute cron cycle. Each tick:\n1. Checks current day + time against folder structure\n2. Posts slot content (or pulls from backlog if empty)\n3. Logs to `posted.log`\n4. Cleans up posted files\n\n## Requirements\n\n- Python 3\n- X API credentials (OAuth 1.0a for posting)\n- A cron runner (OpenClaw cron, system cron, etc.)\n\n## License\n\nMIT\n\nFile v1.0.0:_meta.json\n\n{\n  \"ownerId\": \"kn711gxkbyw34qye3faaqw24yn8163fm\",\n  \"slug\": \"xqueue\",\n  \"version\": \"1.0.0\",\n  \"publishedAt\": 1771857011890\n}","readmeExcerpt":"Skill: Xqueue Owner: madebydia Summary: File-based X/Twitter post scheduler. Drop tweets into day/time folders, they post automatically. No frontend, no app — your file system is the UI. Tags: latest:1.0.6 Version history: v1.0.6 | 2026-06-07T03:31:53.047Z | user Refresh publisher identity and metadata for madebydia v1.0.5 | 2026-03-27T16:00:31.523Z | user Cross-list sync from workspace v1.0.4 | 2026-03-24T16:58:12.6","codeSnippets":[],"executableExamples":[{"language":"text","snippet":"xqueue/\n  config.json\n  backlog/\n    ebook-launch-thread.md\n    ai-tools-roundup.md\n  Sunday/\n    10am/\n      my-tweet.md\n      photo.jpg\n  Monday/\n    9am/\n      thread-about-shipping.md\n    12pm/\n    5pm/\n  Tuesday/\n    ..."},{"language":"bash","snippet":"python3 xqueue-setup.py"},{"language":"text","snippet":"This is my tweet. It can be up to 280 characters."},{"language":"text","snippet":"Post to Build in Public: Just shipped my first ClawHub skill. File-based tweet scheduler, no frontend needed."},{"language":"text","snippet":"I built a file-based tweet scheduler with no frontend. Your filesystem is the UI.\n---\nDrop a .md file into Monday/9am/ and a cron job posts it. Empty slot? It pulls from a backlog/ folder automatically.\n---\nNo database, no app, no dashboard. Just folders and text files. Sometimes the simplest architecture wins."},{"language":"text","snippet":"9am/\n  tweet.md        ← the text\n  progress.png    ← gets attached"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: xqueue\ndescription: File-based X/Twitter post scheduler. Drop tweets into day/time folders, they post automatically. No frontend, no app — your file system is the UI.\nmetadata: {\"openclaw\":{\"requires\":{\"env\":[\"X_CONSUMER_KEY\",\"X_CONSUMER_SECRET\",\"X_ACCESS_TOKEN\",\"X_ACCESS_TOKEN_SECRET\"],\"bins\":[\"python3\"]},\"permissions\":{\"filesystem\":\"read/write within xqueue/ directory\",\"network\":\"api.twitter.com, upload.twitter.com\",\"keychain\":\"optional macOS Keychain if XQUEUE_KEYCHAIN_ACCOUNT is set\"},\"homepage\":\"https://github.com/madebydia/xqueue\",\"author\":\"Diana Park (@madebydia)\"}}\n---\n\n# XQueue\n\nA file-based post scheduler for X (Twitter). Your file system is the UI.\n\n## How It Works\n\nCreate a folder structure with days and times. Drop tweet files into the time slots. A cron job checks every 15 minutes — if it's the right day and time and there's content, it posts and cleans up.\n\n```\nxqueue/\n  config.json\n  backlog/\n    ebook-launch-thread.md\n    ai-tools-roundup.md\n  Sunday/\n    10am/\n      my-tweet.md\n      photo.jpg\n  Monday/\n    9am/\n      thread-about-shipping.md\n    12pm/\n    5pm/\n  Tuesday/\n    ...\n```\n\nThe schedule cycles weekly. Monday's 9am slot fires every Monday at 9am. If the folder is empty, it pulls the oldest file from `backlog/` (sorted alphabetically). If there's content in the slot, it posts that and backlog waits. This means you can schedule up to a week of specific content, and dump everything else in backlog — it'll fill empty slots automatically.\n\nAfter posting, files are deleted (by default) so they don't repeat.\n\n## Setup\n\nRun the setup command to create your queue:\n\n```bash\npython3 xqueue-setup.py\n```\n\nThis asks you:\n1. How many times per day do you want to post?\n2. What times? (or let it pick optimal times)\n3. What timezone?\n4. Any X communities to post to?\n5. Thread separator preference (default: ---)\n6. Delete after posting? (recommended yes — if off, posts may send twice)\n\nCreates the full folder structure + config.json.\n\n## Tweet Format\n\n### Simple tweet\nJust write the text in a `.md` or `.txt` file:\n\n```\nThis is my tweet. It can be up to 280 characters.\n```\n\n### Tweet with community\nStart with `Post to [community name]:` on the first line:\n\n```\nPost to Build in Public: Just shipped my first ClawHub skill. File-based tweet scheduler, no frontend needed.\n```\n\n### Thread\nOne file, tweets separated by your configured separator (default `---`):\n\n```\nI built a file-based tweet scheduler with no frontend. Your filesystem is the UI.\n---\nDrop a .md file into Monday/9am/ and a cron job posts it. Empty slot? It pulls from a backlog/ folder automatically.\n---\nNo database, no app, no dashboard. Just folders and text files. Sometimes the simplest architecture wins.\n```\n\n### Tweet with media\nPut image/video files in the same time folder as the tweet. Supported: JPG, PNG, GIF (under 5MB for images, 15MB for GIF).\n\n```\n9am/\n  tweet.md        ← the text\n  progress.png    ← gets attached\n```\n\nIf multiple media files exist, they att"},{"path":"README.md","content":"# XQueue\n\nA file-based post scheduler for X (Twitter). Your file system is the UI.\n\nNo database. No dashboard. No app. Just folders, text files, and a cron job.\n\n## How It Works\n\n```\nxqueue/\n  config.json\n  backlog/\n  Monday/\n    9am/\n      thread-about-shipping.md\n    12pm/\n    5pm/\n  Tuesday/\n    ...\n```\n\n- **Drop a `.md` file into a day/time folder** → it posts at that time\n- **Empty slot?** → pulls the oldest file from `backlog/` automatically\n- **Schedule cycles weekly** → Monday/9am fires every Monday at 9am\n- **Files are deleted after posting** (configurable) so nothing repeats\n\n## Setup\n\n```bash\npython3 xqueue-setup.py\n```\n\nThe setup wizard asks how many daily posts, what times, timezone, and optional X community targets (paste the community URL, it extracts the ID). Creates the full folder structure + `config.json`.\n\n## Tweet Formats\n\n**Simple tweet** — just text in a `.md` file:\n```\nJust shipped v2. Sometimes the simplest architecture wins.\n```\n\n**Thread** — one file, `---` between tweets:\n```\nI built a file-based tweet scheduler with no frontend. Your filesystem is the UI.\n---\nDrop a .md file into Monday/9am/ and a cron job posts it. Empty slot? It pulls from backlog automatically.\n---\nNo database, no app, no dashboard. Just folders and text files.\n```\n\n**With media** — put images in the same folder (max 4, alphabetical order):\n```\n9am/\n  tweet.md\n  screenshot.png\n```\n\n**Community post** — prefix with the community name:\n```\nPost to Build in Public: Just shipped my first skill. File-based tweet scheduler, no frontend needed.\n```\n\n## Backlog\n\nThe `backlog/` folder holds content without a specific time slot. When a scheduled slot is empty, the oldest backlog file gets posted. Prefix filenames with numbers (`01-`, `02-`) to control order.\n\nWrite a week of content in one sitting, dump it in backlog, and it distributes itself across your empty slots.\n\n## Cron\n\nDesigned to run on a 15-minute cron cycle. Each tick:\n1. Checks current day + time against folder structure\n2. Posts slot content (or pulls from backlog if empty)\n3. Logs to `posted.log`\n4. Cleans up posted files\n\n## Requirements\n\n- Python 3\n- X API credentials via environment variables:\n  - `X_CONSUMER_KEY`, `X_CONSUMER_SECRET` (app credentials)\n  - `X_ACCESS_TOKEN`, `X_ACCESS_TOKEN_SECRET` (user credentials)\n  - Optional: set `XQUEUE_KEYCHAIN_ACCOUNT` to use macOS Keychain as fallback\n- A cron runner (OpenClaw cron, system cron, etc.)\n\n## License\n\nMIT"},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn711gxkbyw34qye3faaqw24yn8163fm\",\n  \"slug\": \"xqueue\",\n  \"version\": \"1.0.6\",\n  \"publishedAt\": 1780803113047\n}"},{"path":"skill-card.md","content":"## Description:\n\nFile-based X/Twitter post scheduler. Drop tweets into day/time folders, they post automatically. No frontend, no app - your file system is the UI.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[madebydia](https://clawhub.ai/user/madebydia)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nExternal users and developers use Xqueue to schedule X/Twitter posts, threads, media posts, and community posts by placing text and media files into day and time folders. It is intended for personal or team social posting workflows that can be run from cron with X API credentials.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: A queue-isolation weakness could allow symlinked files outside the queue to be posted to X under the user's account.\n\nMitigation: Use a private queue directory that untrusted users and processes cannot write to, and avoid symlinks in the queue.\n\nRisk: When deleteAfterPost is enabled, successfully posted content and media are removed after posting.\n\nMitigation: Keep backups of scheduled content and media if retaining originals matters.\n\nRisk: The skill can post scheduled content and media to X using the user's account credentials.\n\nMitigation: Review queued files before enabling cron, start with dryRun when validating setup, and only provide credentials for an account authorized for this posting workflow.\n\n## Reference(s):\n\n- [ClawHub Skill Page](https://clawhub.ai/madebydia/skills/xqueue)\n- [Xqueue Homepage](https://github.com/madebydia/xqueue)\n\n## Skill Output:\n\n**Output Type(s):** [guidance, shell commands, configuration]\n\n**Output Format:** [Markdown guidance with shell commands and JSON configuration examples]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Produces setup and operating guidance for a local file-based queue; posting behavior depends on the user's configured cron schedule, queue contents, and X API credentials.]\n\n## Skill Version(s):\n\n1.0.6 (source: server-resolved release metadata)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment."}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":"File-based X/Twitter post scheduler. Drop tweets into day/time folders, they post automatically. No frontend, no app — your file system is the UI. Skill: Xqueue Owner: madebydia Summary: File-based X/Twitter post scheduler. Drop tweets into day/time folders, they post automatically. No frontend, no app — your file system is the UI. Tags: latest:1.0.6 Version history: v1.0.6 | 2026-06-07T03:31:53.047Z | user Refresh publisher identity and metadata for madebydia v1.0.5 | 2026-03-27T16:00:31.523Z | user Cross-list sync from workspace v1.0.4 | 2026-03-24T16:58:12.6","editorialQuality":{"score":100,"threshold":65,"status":"ready","wordCount":1354,"uniquenessScore":47,"reasons":[]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-10T05:47:51.138Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-10T05:47:51.138Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-10T10:42:24.988Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}