Twitter logo

Twitter

Organization
runxhq
twitter

Govern X (Twitter) account work through three lanes: evidence reads, typed act plans for posting and account hygiene, and gated execution with per-act provider evidence. Nothing reaches a live timeline or mutates an account without an explicit approval recorded in the receipt.

Overview

Publisherrunxhq
Repositoryrunx
Skill nametwitter
Stars
105
Forks
109
Bundled files
13
LicenseApache-2.0
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • 13 bundled files

    Scripts, templates, and references the model can read while it works. Files are read-only and never executed.

  • Open source

    Published by runxhq on GitHub. Read the source before you install it.

Installation

Install the Twitter AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/runxhq/runx/tree/main/skills/twitter
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/runxhq/runx.git /tmp/runx
mkdir -p .claude/skills
cp -r /tmp/runx/skills/twitter .claude/skills/twitter
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Twitter in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Twitter on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Twitter is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

Twitter

One account, three lanes: read evidence, plan typed acts, execute an approved plan.

This is the public branded X (Twitter) catalog skill for the message-send action family. Its core invariant: the agent may read, audit, draft, and plan freely, but every act that publishes to a public timeline or mutates the account stops at a human approval gate, and the sealed receipt proves which acts ran, against which plan digest, with which provider evidence.

Write for the operator who owns the account, the reviewer who approves a live act, and downstream skills that consume the resulting packets. Keep each plan to the smallest evidence-backed act set that satisfies the objective. Existing post and user ids must come from supplied evidence, never memory or guesswork; name missing evidence as a blocker.

What this skill does

Seven runners:

  • read: collect account evidence from the live API through the twitter connector. Queries: snapshot, posts, mentions, search, following, followers. A query without params.user_id reads the authenticated account; with it, another account. The connector reads whole pages until it has at least max_items, keeps every item of them, and reports in next_cursor where a further read starts (pass it back as params.pagination_token). Emits runx/twitter.evidence.v1. Read-only; no gate.
  • read-archive: inspect one contained X archive export (tweets.js, following.js, or follower.js) through the runtime's digest-bound artifact page seam. Twitter code receives bounded, record-complete pages and never a path or whole-file escape hatch. The runtime snapshots up to 512 MiB and this skill requests 512 KiB pages; the page size is not a total archive limit. Emits the same runx/twitter.evidence.v1 packet; no gate.
  • plan: turn one bounded objective plus evidence into runx/twitter.plan.v1, an explicit list of typed acts with rationale, using agent judgment, then bind the exact plan through native data.digest. This is the curated lane, for dozens of acts that each deserve a reason. A plan is a draft; it delivers nothing. The result exposes twitter_plan.data and the matching digest_result.data.digest required by execute; callers never calculate the digest themselves.
  • select: the bulk lane. Apply a deterministic predicate to an archive export and emit a compact plan, no agent judgment. Use it when the criterion is mechanical and the match set runs to thousands, where a per-item rationale would be wrong and would exceed the runtime output limit. Two targets: posts pages tweets.js and emits delete_post acts (predicate: author, date range, engagement threshold), with identical results across page sizes; users reads a bounded following.js bundle and emits unfollow acts (predicate: non_mutual: true for accounts you follow that do not follow back, needing follower.js too, or an explicit user_ids list). Emits runx/twitter.selection.v1 carrying a digest-bound twitter_plan.
  • execute: run the next batch of an approved plan as one twitter connector operation behind its own approval, sealing per-act outcomes into runx/twitter.execution.v1 and appending one compact progress fact to a durable execution ledger. A batch is one published act (a post, reply, quote, or one thread segment), or the contiguous run of up to 50 acts of one other kind from the cursor. The approval binds that exact call. The kernel records each act's outcome as it lands and stops sending at a rate limit, so a monotonic cursor, not an accumulated id list, is enough to resume safely.

Durable operation memory and continuation

The skill remembers an operation in its bound store, local to the workspace by default. It saves the exact plan once under its native digest, separately from the compact execution progress stream. The saved plan preserves the objective, account principal, exact content and targets, rationale, evidence references and any applied context bindings. Progress preserves the pinned account id, next act, partial thread cursor, cumulative processed, succeeded and failed act counts, a bounded last failure evidence reference, the last batch summary and structured stop advice. No host opens the store database, reconstructs completed ids or calculates plan hashes.

On the first execute, supply plan_json and its native plan_digest from plan or select. A valid plan is saved before the effect approval; saving it is not approval. On later calls, omit plan_json and supply only the digest. The skill reads its own progress, selects the next batch and derives the expected stream version and canonical retry key. The logical store defaults to local://twitter; pass data_source_uri when the operation uses another binding, and keep using that same workspace and store.

  • status reads one plan and its progress without contacting X. It returns the objective, principal, current cursor, partial thread, last batch, next batch summary, cumulative outcome counts, failure evidence, structured stop, retry_at, and compact next_input for execute. It never returns an approval or claims a proposed batch has run. needs_plan means this store has no saved plan: provide the original exact plan once, rather than inventing it or resetting a progress stream.
  • recent lists a bounded page of prior execution summaries and plan digests. It does not scan history or return every post. A plan saved at an approval pause has no completed batch yet; find that paused invocation through native run history and resume its run id.

Each execution reads the bound account. It runs only when that account matches the plan's principal (account:@handle, case insensitive) and, once progress has pinned an account id, that same account. The exact approval identifies the verified handle, account id, target and payload. Another available account is never a fallback.

A native invocation and a multi-batch plan have different identities. If the invocation pauses, continue that run id through runx resume; do not start another run to escape an approval. If a call is interrupted or its outcome is unknown, read native history and reconcile that same invocation first. Runx owns in-flight custody and whether an effect may be retried. Only after a batch is sealed and its result understood should another execute start the next batch. A saved plan, status, receipt or supplied approval reference is context, never new authority. Relay only actual operator decisions bound to the exact native request.

Threads advance one segment per batch. The saved cursor contains the next segment and confirmed reply id, so continuation does not repost earlier segments. The cursor counts processed acts. Only provider-confirmed successful acts increment counts.succeeded; settled refusals increment counts.failed. A partially published thread is not a completed act. Failures remain visible across later batches through cumulative counts and a bounded last_failure containing the act, reason and native evidence reference. At the end, execution returns completed_with_failures and status returns complete_with_failures when any terminal act failed. Detailed outcomes remain in native evidence. A refused plan, digest mismatch or already-complete plan does not append a fake progress event.

stop.action distinguishes wait, review and reconcile. A known rate reset gives waiting status and a conditional next_input: the host must wait until retry_at before using it. Unknown retry timing or account, authentication and billing problems require review and expose no automatic next input. An unsettled or ambiguous outcome asks for native reconciliation; never start a replacement publish invocation to escape it. After resolving a review stop, an operator may explicitly invoke execute again under a fresh exact native approval. retry_at is the provider's reported reset, not proof the account will be ready then. Wait until that time before another attempt, or stop for the operator when retry timing is unknown. Inspect native failure evidence for calls that fail before a settled batch result. Do not loop on permission, billing, account restrictions or unknown acknowledgement. The host owns scheduling and may choose a stricter cadence or spending cap. A CLI host can return the wait to its operator; Fieldwork can persist a wakeup on its Work. The skill contains no sleeping process, scheduler or personal memory service.

Direct CLI use

Use the installed CLI's inspection for exact input contracts. Select the workspace and connector once, then use the same workspace for continuation:

sh
runx connector use twitter --credential user
runx connector use store
runx skill ./skills/twitter read -i query=snapshot --json
runx skill ./skills/twitter recent --json
runx skill ./skills/twitter status -i plan_digest=<native-plan-digest> --json
runx skill ./skills/twitter execute -i plan_digest=<native-plan-digest> --json

For the first execution, --inputs <file-or-stdin> carries the original plan and native digest; subsequent executions use the compact next_input from status. Local paths above illustrate a checkout; installed registry packages and other compatible hosts use the same runner contracts. Paths, run ids and artifact references come from runx, never guessed filesystem layouts.

The operating sequence is evidence → grounded plan or deterministic selection → exact native approval → bounded execution → status or native recovery. Codex supplies judgment and relays the person's decisions. It needs no X HTTP, SQL, batching, canonical hashing or private operator scripts. Fieldwork owns ongoing goals, brand/taste context, longer-lived memory and future wakeups; the same skill and native evidence work from either host.

Connector implementations

The skill targets typed X operations, not an HTTP library or browser driver. An API implementation and an X-specific browser implementation can implement the same operations if they preserve account binding, exact payload semantics, bounded outcomes, idempotency/custody requirements and truthful finality. A generic browser connector alone does not implement post.create or users.follow: its X-specific implementation must translate those operations and verify their results. Bind an implementation explicitly; do not silently switch transport or account after a failure. Missing operations are readiness failures, not permission to fall back to ad hoc browser or HTTP code. The current packaged connector uses the X API; this skill change does not supply or claim a working browser implementation.

Each runner emits exactly one packet for its lane: typed evidence with provenance and a content digest, a curated or bulk act plan bound by digest, or provider outcomes bound to the executed plan digest and appended to the ledger.

The act vocabulary, with its consequence class:

kindconsequenceparams
postpublic_sendtext
replypublic_sendtext, in_reply_to
quotepublic_sendtext, quote_of
threadpublic_sendtexts (ordered, max 25)
repostpublic_sendpost_id
delete_postlive_mutationpost_id
unfollowlive_mutationtarget_user_id
mutelive_mutationtarget_user_id
blocklive_mutationtarget_user_id
followlive_mutationtarget_user_id
likelive_mutationpost_id

Every kind is consequential, so every plan sets gates.human_approval_required: true. follow, like, and repost are engagement acts and share a hard cap of 10 per plan. Direct messages are outside this skill.

A published act is confirmed by reading the post back. The other kinds are acknowledged: X answers each with the resulting state (following: false, deleted: true), which is the evidence, and has no read of one follow or like cheap enough to confirm a batch. They set a state, so resending one changes nothing. An answer that does not state the resulting state stops the cursor at that act, and a later batch sends it again.

Post and reply text, and each thread segment, is a non-empty string of at most 4000 characters, published verbatim; ids are X id strings. A plan that breaks either is refused before approval.

When to use this skill

  • Promote a release, publish a thread, or reply to a mention on behalf of a named principal, with content bound verbatim in the plan.
  • Audit an account's own post history or following list and prune it: bulk delete old posts, unfollow low-value accounts, against operator-stated criteria.
  • Gather timeline, mention, or search evidence for downstream research, triage, or lead skills that consume runx/twitter.evidence.v1.
  • Route a message-send plan onto X as its provider delivery lane.

When not to use this skill

  • To send direct messages or manage DM conversations.
  • To farm engagement: follow-churn, mass liking, coordinated reposting, or any volume pattern designed to game visibility. The engagement cap is not a budget to fill.
  • To mention, reply to, or dogpile users who have not engaged with the principal, at volume.
  • To operate an account the operator does not control, or to automate consumer account creation.
  • To bypass the approval gate, the act caps, or the operator's spending limit on the pay-per-use API.

Procedure

For the plan runner, build twitter_plan this way:

  1. Hold one bounded objective. If the ask bundles unrelated jobs (a promo thread plus a follow purge), return needs_input with the split.
  2. Ground every reference. Ids for delete_post, unfollow, reply, quote, like, mute, and block must come from evidence_json or an explicit operator-supplied id. If the evidence is missing or stale, name it as a blocker; never invent or approximate an id.
  3. Write public content into the act params verbatim: the exact text or texts to publish, shaped by brand_context when supplied. Do not plan a summary of what will be written; approval binds the exact words.
  4. Give every act a stable act_id (act-001 onward), its kind, params, its consequence from the table, and a one-line rationale tied to the objective or the operator's stated criteria.
  5. Apply operator_policy narrowly. A prune criterion like "no engagement and older than 2023" selects only posts the evidence shows meet it; borderline items go to open_questions, not into the act list.
  6. Keep the plan small: at most 50 acts, at most 10 engagement acts, threads at most 25 segments. A larger job becomes staged plans.
  7. Set decision: ready when acts are grounded and complete; needs_input for missing objective, principal, evidence, or content; reject for asks outside the vocabulary or inside the abuse boundaries.
  8. Never place credentials, bearer tokens, raw API dumps, or third-party personal data beyond public ids and handles in the plan.

Edge cases and stop conditions

  • Mixed objective: return needs_input with the runner or plan split.
  • Id not in evidence: blocker; the plan stays needs_input.
  • Prune criteria ambiguous: select the unambiguous items, list the rest in open_questions.
  • Rate limit or provider refusal during read: the read fails with the provider's reason; a read is whole or it fails.
  • Oversized user-selection archive: the current two-file users selector refuses when either bounded text file exceeds the native read limit; it never treats truncation as an empty following/follower set. read-archive itself remains paged. Do not claim an oversized users bulk plan was evaluated.
  • Rate limit during execute: nothing more is sent; the acts before it are settled and the packet reports next_act_index, remaining_count, and the reset time. After the reset, inspect status and invoke its compact next input; the skill reads and verifies the latest stream version itself.
  • One act refused: a refused act is recorded as failed with the provider's reason and the cursor moves past it. Unfollowing a deactivated account is already the state the act asked for, so it counts as done.
  • Plan digest mismatch on execute: the apply step refuses and executes nothing. A refusal is receipt evidence, not a fake ledger transition.
  • Concurrent or interrupted work: reconcile the native run first. The skill derives its stream version and batch key; a host must not invent either.
  • Partially posted thread: resume from the ledger's active_thread cursor; never restart the thread from its first confirmed segment.
  • Approval missing or denied: the execute graph stops at the gate.
  • No bound account: admission refuses before any provider call; bind one with runx connector use twitter --credential user.
  • Fully autonomous live posting requested: reject; the gate is the contract.

Outputs

  • read and read-archive return runx/twitter.evidence.v1: typed post or user records with metrics, the cursor the next live read starts from, and provenance naming the provider answers or archive artifact by digest.
  • plan returns runx/twitter.plan.v1 as twitter_plan.data, with its digest as digest_result.data.digest. Each act carries its consequence and rationale, and context_bindings preserve the exact brand or taste context the planner applied.
  • select returns runx/twitter.selection.v1: the matched records and the twitter_plan a driver hands to execute, with plan_digest bound so the approved and executed bytes are provably identical.
  • execute returns runx/twitter.execution.v1 for the current bounded batch: each act's result, where the next batch resumes, cumulative counts, any structured stop, and the provider's reported rate and reset, which the next host needs.

Worked example

Input: objective "delete my zero-engagement posts from before 2024", principal account:@example, evidence from read-archive(query: posts, archive_file: data/tweets.js) showing three matching posts, operator_policy "keep anything with replies".

Output: decision: ready; three delete_post acts, each carrying the post id from the evidence and a rationale quoting its age and zero metrics; gates.human_approval_required: true; one borderline post with two replies listed in open_questions. Execution then stops at the approval gate, and the sealed receipt binds the approved digest to the three deletions the provider confirmed.

Inputs

  • read: query (required), params (user_id, q, pagination_token), max_items.
  • read-archive: query and relative archive_file (required), archive_base (workspace default, or skill for packaged fixtures), and max_items.
  • plan: objective (required), principal (required), evidence_json, operator_policy, brand_context, operator_context.
  • select: objective (required), principal (required), target (posts default, or users), archive_file (posts), following_file and followers_file (users), predicate (required: posts take rt_of, is_retweet, text_prefix, text_contains, max_likes, max_reposts, before_year, after_year; users take non_mutual or user_ids), archive_base, max_acts.
  • execute: plan_digest (required), optional plan_json on the first call, data_source_uri (default local://twitter) and max_acts (1–50). Native digest verification precedes saving the plan or provider effects. Version, retry identity and next batch are derived inside the skill.
  • status: plan_digest (required), optional data_source_uri and max_acts.
  • recent: optional data_source_uri, limit (1–100, default 5) and page cursor. Only execution summaries are listed.

Credentials and cost

The twitter connector declares two credentials, and the bound account's credential decides how a request authenticates. Credentials never appear as inputs or receipt material.

  • user: one JSON object holding consumer_key, consumer_secret, access_token, access_secret (OAuth 1.0a user context). Required for every mutation and for the authenticated account's own reads. Bind it with runx connector use twitter --credential user, the JSON on stdin.
  • app: the app-context bearer token, enough for search and reads that name another account by user_id. Bind it with runx connector use twitter --credential app, the token on stdin.

The X API bills per request on current plans and a post containing a link costs a large multiple of a plain one, so prefer archive exports for bulk history, set a spending cap in the developer portal, and let max_items and the act caps bound each run.

Agent task contract

twitter-plan

Follow the plan procedure and act vocabulary above. Return one twitter_plan containing decision, objective, principal, typed acts, approval gates, evidence locators, open questions, blockers, and a truthful success checkpoint. Every referenced post or user id must be grounded in supplied evidence, and every public word must appear verbatim in the act params. A plan never executes, publishes, deletes, follows, or otherwise mutates the account.

Bundled files

The model reads these on demand while the skill is loaded. They are exposed as readable files and are never executed.

Frequently asked questions

What does the Twitter AI skill do?

Govern X (Twitter) account work through three lanes: evidence reads, typed act plans for posting and account hygiene, and gated execution with per-act provider evidence. Nothing reaches a live timeline or mutates an account without an explicit approval recorded in the receipt.

Why use Twitter on TypingMind?

Because you install it once and use it with any model. Twitter is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Twitter in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/runxhq/runx/tree/main/skills/twitter. TypingMind reads its SKILL.md and bundles its files and installs it as a skill you can enable per chat.

Which AI models can use Twitter?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Twitter?

As many as you like. As long as a model supports skills, you can use Twitter with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Twitter AI skill free?

Yes. It is published on GitHub by runxhq under the Apache-2.0 license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇