Files
wehub-resource-sync 426e9eeabd
Benchmark Bridge Tests / benchmark (bunx @biomejs/biome check packages/lifeops-bench/src, benchmark-lint) (push) Waiting to run
Benchmark Bridge Tests / benchmark (bunx vitest run --config packages/lifeops-bench/vitest.config.ts --root packages/lifeops-bench --passWithNoTests, benchmark-tests) (push) Waiting to run
Build Agent Image / build-and-push (push) Waiting to run
Chat shell gestures / Chat shell gesture + parity e2e (push) Waiting to run
ci / test (push) Waiting to run
ci / lint-and-format (push) Waiting to run
ci / build (push) Waiting to run
ci / dev-startup (push) Waiting to run
Cloud Gateway Discord / Test (push) Waiting to run
Cloud Gateway Webhook / Test (push) Waiting to run
Cloud Tests / lint-and-types (push) Waiting to run
Cloud Tests / unit-tests (push) Waiting to run
Cloud Tests / integration-tests (push) Waiting to run
Cloud Tests / e2e-tests (push) Blocked by required conditions
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
Deploy Apps Worker (Product 2) / Determine environment (push) Waiting to run
Deploy Apps Worker (Product 2) / Deploy apps worker to apps-control host (${{ needs.determine-env.outputs.environment }}) (push) Blocked by required conditions
Deploy Eliza Provisioning Worker / Determine environment (push) Waiting to run
Deploy Eliza Provisioning Worker / Deploy worker to Hetzner host (${{ needs.determine-env.outputs.environment }} @ ${{ needs.determine-env.outputs.deployment_sha }}) (push) Blocked by required conditions
Dev Smoke / Classify changed paths (push) Waiting to run
Dev Smoke / bun run dev onboarding chat (push) Blocked by required conditions
Dev Smoke / Vite HMR dependency-level smoke (push) Blocked by required conditions
Electrobun Submodule Guard / electrobun gitlink is fetchable (push) Waiting to run
gitleaks / gitleaks (push) Waiting to run
Markdown Links / Relative Markdown Links (push) Waiting to run
Publish @elizaos/example-code / check_npm (push) Waiting to run
Publish @elizaos/example-code / publish_npm (push) Blocked by required conditions
Publish @elizaos/plugin-elizacloud / verify_version (push) Waiting to run
Publish @elizaos/plugin-elizacloud / publish_npm (push) Blocked by required conditions
Quality (Extended) / Homepage Build (PR smoke) (push) Waiting to run
Quality (Extended) / Comment-only diff guard (push) Waiting to run
Quality (Extended) / Format + Type Safety Ratchet (push) Waiting to run
Quality (Extended) / Develop Gate (secret scan + UI determinism) (push) Waiting to run
Quality (Extended) / Develop Gate (lint) (push) Waiting to run
Sandbox Live Smoke / Sandbox live smoke (push) Waiting to run
Snap Build & Test / Build Snap (amd64) (push) Waiting to run
Snap Build & Test / Build Snap (arm64) (push) Waiting to run
supply-chain / sbom (push) Waiting to run
supply-chain / vulnerability-scan (push) Waiting to run
Build, Push & Deploy to Phala Cloud / build-and-push (push) Waiting to run
Test Packaging / Validate Packaging Configs (push) Waiting to run
Test Packaging / PyPI on Python ${{ matrix.python }} (push) Waiting to run
Test Packaging / Pack & Test JS Tarballs (push) Waiting to run
Test Packaging / elizaos CLI global-install smoke (node + bun) (push) Waiting to run
UI Fixture E2E / ui-fixture-e2e (push) Waiting to run
UI Fixture E2E / fixture-e2e (push) Waiting to run
UI Story Gate / story-gate (push) Waiting to run
vault-ci / test (macos-latest) (push) Waiting to run
vault-ci / test (ubuntu-latest) (push) Waiting to run
vault-ci / test (windows-latest) (push) Waiting to run
vault-ci / app-core wiring tests (push) Waiting to run
verify-patches / verify patches/CHECKSUMS.sha256 (push) Waiting to run
Voice Benchmark Smoke / voice-emotion fixture smoke (push) Waiting to run
Voice Benchmark Smoke / voiceagentbench fixture smoke (push) Waiting to run
Voice Benchmark Smoke / voicebench-quality unit smoke (push) Waiting to run
Voice Benchmark Smoke / voicebench TypeScript unit (no audio) (push) Waiting to run
Voice Benchmark Smoke / voice bench smoke summary (push) Blocked by required conditions
Windows CI / windows ([bun run --cwd packages/app-core test bun run --cwd packages/elizaos test bun run --cwd packages/cloud/shared test], app-and-cli) (push) Waiting to run
Windows CI / windows ([bun run --cwd packages/scenario-runner test bun run --cwd packages/vault test bun run --cwd packages/security test bun run --cwd plugins/plugin-coding-tools test], framework-packages) (push) Waiting to run
Windows CI / windows ([bun run --cwd plugins/plugin-elizacloud test bun run --cwd plugins/plugin-discord test bun run --cwd plugins/plugin-anthropic test bun run --cwd plugins/plugin-openai test bun run --cwd plugins/plugin-app-control test bun run --cwd plugins/pl… (push) Waiting to run
Windows CI / windows ([node packages/scripts/run-turbo.mjs run build --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/agent --concurrency=4 node packages/scripts/run-bash-linux-only.mjs scripts/verify-riscv64-buildpaths.sh node packages/scripts/run… (push) Waiting to run
Windows CI / windows ([node packages/scripts/run-turbo.mjs run typecheck --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/cloud-shared --concurrency=4 bun run --cwd packages/core test bun run --cwd packages/shared test], core-runtime, 75) (push) Waiting to run
Test Packaging / Build & Test PyPI Package (push) Waiting to run
Voice Workbench / headless workbench (mocked backends) (push) Has been cancelled
Voice Workbench / real acoustic lane (nightly, provisioned only) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:43:05 +08:00
..

@elizaos/plugin-x

X (formerly Twitter) connector for elizaOS agents, built on the official Twitter API v2 (twitter-api-v2).

It adds an XService to the agent runtime that registers an X message connector (DMs) and post connector (public tweets), and runs optional autonomous loops for posting, mention/reply handling, timeline actions, and content discovery. The plugin registers no actions, providers, or evaluators — all agent-facing behavior flows through the connector handlers.

The plugin auto-enables when a connectors.x (or legacy connectors.twitter) block is present in agent config and is not explicitly disabled.

Authentication

Two auth modes, selected by TWITTER_AUTH_MODE:

  • env (default) — OAuth 1.0a static credentials. Requires TWITTER_API_KEY, TWITTER_API_SECRET_KEY, TWITTER_ACCESS_TOKEN, TWITTER_ACCESS_TOKEN_SECRET. The Twitter app must have Read and write permissions; after enabling write, regenerate the access token + secret.
  • oauth — OAuth 2.0 PKCE (login + approve). Requires TWITTER_CLIENT_ID and TWITTER_REDIRECT_URI (loopback recommended). No client secret is used or stored. On first run the plugin prints an authorization URL and captures the callback; tokens persist per accountId via the runtime cache and connector credential store (no local token file).

Getting credentials

  1. Create an app in the Twitter Developer Portal with API v2 access.
  2. Under User authentication settings, set App permissions: Read and write.
  3. For env mode, copy API Key/Secret (Consumer Keys) and Access Token/Secret (Authentication Tokens). For oauth mode, copy the OAuth 2.0 Client ID.

Configuration

Set via the agent's settings or environment. All values are read with getSetting(runtime, key), which checks runtime settings before process.env. Intervals are in minutes unless noted.

# Auth (env mode shown)
TWITTER_AUTH_MODE=env
TWITTER_API_KEY=...
TWITTER_API_SECRET_KEY=...
TWITTER_ACCESS_TOKEN=...          # must have write permission
TWITTER_ACCESS_TOKEN_SECRET=...

# OAuth 2.0 PKCE alternative
# TWITTER_AUTH_MODE=oauth
# TWITTER_CLIENT_ID=...
# TWITTER_REDIRECT_URI=http://127.0.0.1:8080/callback
# TWITTER_SCOPES="tweet.read tweet.write users.read offline.access"

# Feature toggles (all opt-in except replies)
TWITTER_ENABLE_POST=false         # autonomous posting loop
TWITTER_ENABLE_REPLIES=true       # mention/reply handling
TWITTER_ENABLE_ACTIONS=false      # timeline likes/retweets/quotes
TWITTER_ENABLE_DISCOVERY=         # defaults to true when ACTIONS=true, unless set false

# Behavior
TWITTER_DRY_RUN=false             # simulate writes, post nothing
TWITTER_POST_IMMEDIATELY=false    # post once on startup
TWITTER_TARGET_USERS=             # comma-separated usernames; empty or "*" = all
TWITTER_NICKNAMES=                # comma-separated nicknames the agent answers to (TWITTER_IDENTITY provider)
TWITTER_MAX_TWEET_LENGTH=280
TWITTER_RETRY_LIMIT=5

# Timing (minutes; MIN/MAX add randomness, else the fixed value is used)
TWITTER_POST_INTERVAL=120
TWITTER_POST_INTERVAL_MIN=90
TWITTER_POST_INTERVAL_MAX=180
TWITTER_ENGAGEMENT_INTERVAL=30
TWITTER_ENGAGEMENT_INTERVAL_MIN=20
TWITTER_ENGAGEMENT_INTERVAL_MAX=40
TWITTER_DISCOVERY_INTERVAL_MIN=15
TWITTER_DISCOVERY_INTERVAL_MAX=30

# Discovery limits
TWITTER_MAX_ENGAGEMENTS_PER_RUN=5
TWITTER_MIN_FOLLOWER_COUNT=100
TWITTER_MAX_FOLLOWS_PER_CYCLE=5

Multi-account routing: provide account-scoped credentials in TWITTER_ACCOUNTS (JSON) or register accounts via the runtime's ConnectorAccountManager. TWITTER_DEFAULT_ACCOUNT_ID selects the default account (effective default: "default").

For the full validated schema and defaults see src/environment.ts (twitterEnvSchema, validateTwitterConfig). For an exhaustive variable table and architecture notes see CLAUDE.md.

Discovery service

When enabled, the discovery service searches for content matching the agent's topics (falling back to its bio), scores accounts and tweets, and engages. Relevance thresholds (in src/discovery.ts): like ≥ 0.5, reply ≥ 0.7, quote ≥ 0.85. Engaged tweets and followed accounts are tracked to avoid duplicates.

src layout

src/
  index.ts                 XPlugin (services: XService, XWorkflowCredentialProvider)
  base.ts                  ClientBase — twitter-api-v2 wrapper, profile/timeline/search
  environment.ts           twitterEnvSchema, validateTwitterConfig
  types.ts                 TwitterClientState, ITwitterClient, Tweet, MediaData, event payloads
  post.ts                  TwitterPostClient — posting loop
  interactions.ts          TwitterInteractionClient — mention/reply loop
  timeline.ts              TwitterTimelineClient — timeline action loop
  discovery.ts             TwitterDiscoveryClient — discovery loop
  connector-account-provider.ts, connector-credential-refs.ts, workflow-credential-provider.ts
  client/                  Low-level API: client.ts, tweets.ts, profile.ts, search.ts,
                           relationships.ts, accounts.ts, auth.ts, errors.ts, auth-providers/
  services/                XService (x.service.ts), Post/Message services + interfaces
  utils/                   settings.ts, memory.ts, time.ts, error-handler.ts

Commands

bun run --cwd plugins/plugin-x build           # tsup → dist/
bun run --cwd plugins/plugin-x dev             # tsup --watch
bun run --cwd plugins/plugin-x test            # vitest run
bun run --cwd plugins/plugin-x test:coverage   # vitest run --coverage
bun run --cwd plugins/plugin-x lint            # biome check --write --unsafe
bun run --cwd plugins/plugin-x format          # biome format --write

Troubleshooting

  • 403 on post or engagement — app is read-only, or you're engaging a protected/own tweet. Set Read and write permissions, regenerate the access token + secret, and restart.
  • "Could not authenticate you" — credentials don't match the selected TWITTER_AUTH_MODE. In env mode use Consumer Keys + Authentication Tokens; in oauth mode use the OAuth 2.0 Client ID and a loopback redirect URI (no client secret).
  • Bot not posting — confirm TWITTER_ENABLE_POST=true, the character has bio/topics/messageExamples for generation, and try TWITTER_POST_IMMEDIATELY=true.

Resources