| Crates.io | xfiles |
| lib.rs | xfiles |
| version | 0.4.5 |
| created_at | 2026-01-16 10:26:21.712158+00 |
| updated_at | 2026-01-19 10:31:59.848263+00 |
| description | Persistence of data using X, formerly known as Twitter, as a public filesystem. |
| homepage | https://github.com/cryptopatrick/xfiles |
| repository | https://github.com/cryptopatrick/xfiles |
| max_upload_size | |
| id | 2048388 |
| size | 194,340 |
Author's bio: ππ Hi, I'm CryptoPatrick! I'm currently enrolled as an
Undergraduate student in Mathematics, at Chalmers & the University of Gothenburg, Sweden.
If you have any questions or need more info, then please join my Discord Channel: AiMath
What is xfiles β’ Features β’ How To Use β’ Documentation β’ License
xfiles is a Rust library that treats Twitter as a public, append-only, log-structured filesystem. Tweets become "files", replies become "commits", and a local SQLite index keeps traversal fast.
Why? For transparent AI agents, public verifiability, distributed state, and creative experiments where Twitter serves as a globally verifiable shared memory bus.
Tweet (root) β File
Reply β Commit
Thread β Version history
SQLite β Local index/cache
xfiles provides a complete filesystem abstraction over Twitter with persistent local caching:
open(path, Create) posts a root tweetread() fetches content from Twitter (cached locally)write(content) posts reply commitshistory(path) retrieves full commit chainlist(dir) shows all files in a directoryexists(path) queries local indexββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β User Application (Agent/CLI/Backend) β
β Single call: fs.open().write() β
ββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββ
β
ββββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββββ
β XFS Component β
β β’ Open files (create root tweets) β
β β’ Read content (fetch from Twitter) β
β β’ Write updates (post reply tweets) β
β β’ List files (query SQLite index) β
β β’ Track history (traverse DAG) β
ββββββββββββββββ¬βββββββββββββββββββββββββββ¬βββββββββββββββββ
β β
βββββββββΌβββββββββ ββββββββββΌββββββββββ
β Twitter Adapterβ β SQLite Store β
β β’ API calls β β β’ Commit index β
β β’ Rate limit β β β’ File mapping β
β β’ Chunking β β β’ Cache layer β
ββββββββββ¬ββββββββ ββββββββββββββββββββ
β
βββββββββΌβββββββββ
β Twitter API β
β β’ GET tweet β
β β’ POST tweet β
β β’ GET replies β
ββββββββββββββββββ
User β XFS β SQLite Index + Twitter API β Remote Storage
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β file.write("Agent state v2") β
ββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββ
β
ββββββββββΌβββββββββ
β 1. Compute β
β Hash β
β (blake3) β
βββββββββββ¬ββββββββ
β
β content hash
βΌ
ββββββββββββββββββββββ
β 2. Chunk β
β Content β
β (if >280 chars) β
βββββββββββ¬βββββββββββ
β
β chunks[]
βΌ
ββββββββββββββββββββββ
β 3. Post Reply β
β to Twitter β
β (TwitterAdapter) β
βββββββββββ¬βββββββββββ
β
β tweet_id
βΌ
ββββββββββββββββββββββ
β 4. Create Commit β
β β’ id = tweet_id β
β β’ parent = head β
β β’ hash, timestamp β
βββββββββββ¬βββββββββββ
β
βΌ
ββββββββββββββββββββββ
β 5. Store Commit β
β in SQLite β
β β’ Update index β
β β’ Mark as head β
β β’ Cache content β
ββββββββββββββββββββββ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β XFS β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Public API β β
β β β’ open(path, mode) β XFile β β
β β β’ list(dir) β Vec<String> β β
β β β’ history(path) β Vec<Commit> β β
β β β’ exists(path) β bool β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β β
β ββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββ
β β XFile Operations ββ
β β β’ read() β Vec<u8> ββ
β β β’ write(content) β Result<()> ββ
β β β’ delete() β Result<()> ββ
β ββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββ
βββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββ
β
βββββββββββββββββββΌβββββββββββββββββββββ
β SQLite Database (file.db) β
β βββββββββββββββββββββββββββββββββββ β
β β files β β
β β - path (PK) β β
β β - root_tweet_id β β
β β - created_at β β
β βββββββββββββββββββββββββββββββββββ β
β β
β βββββββββββββββββββββββββββββββββββ β
β β commits β β
β β - tweet_id (PK) β β
β β - parent_id (JSON array) β β
β β - timestamp β β
β β - author β β
β β - hash (blake3) β β
β β - mime β β
β β - size β β
β β - head (boolean) β β
β βββββββββββββββββββββββββββββββββββ β
β β
β βββββββββββββββββββββββββββββββββββ β
β β chunks β β
β β - tweet_id (PK) β β
β β - parent_commit (FK) β β
β β - idx (chunk order) β β
β β - size, hash β β
β βββββββββββββββββββββββββββββββββββ β
ββββββββββββββββββββββββββββββββββββββββ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β User calls file.write(content) β
βββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 1. Chunk Content β
β β’ Split into 280-byte chunks if needed β
β β’ Compute blake3 hash of full content β
βββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 2. Post to Twitter API β
β β’ Post first chunk as reply to current head β
β β’ Post remaining chunks as reply chain β
β β’ Receive tweet_id for each chunk β
βββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 3. Create Commit Object β
β β’ id = first chunk tweet_id β
β β’ parents = [current_head] β
β β’ hash = content hash β
β β’ timestamp = now() β
β β’ author = username β
βββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 4. Persist to SQLite β
β β’ INSERT INTO commits β
β β’ UPDATE files SET head β
β β’ Cache content for fast reads β
βββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 5. Publicly Visible on Twitter β
β β’ Tweet URL: https://twitter.com/i/web/status/{id} β
β β’ Timestamped by Twitter β
β β’ Immutable and auditable β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Add xfiles to your Cargo.toml:
[dependencies]
xfiles = "0.1"
tokio = { version = "1", features = ["full"] }
Or install with cargo:
cargo add xfiles
Before using xfiles with real Twitter, you need API credentials:
export TWITTER_BEARER_TOKEN="your_bearer_token_here"
export TWITTER_USERNAME="your_username"
use xfiles::*;
use std::sync::Arc;
#[tokio::main]
async fn main() -> Result<()> {
// Use mock adapter for testing (no Twitter API needed)
let adapter = Arc::new(MockAdapter::new());
let mut fs = XFS::with_adapter("agent", adapter, Some(":memory:")).await?;
// Create and write to file
let mut file = fs.open("memory.txt", OpenMode::Create).await?;
file.write(b"Agent state v1").await?;
// Read it back
let content = file.read().await?;
println!("{}", String::from_utf8_lossy(&content));
// Multiple writes create commit chain
file.write(b"Agent state v2").await?;
file.write(b"Agent state v3").await?;
// Get history
let history = fs.history("memory.txt").await?;
println!("Total commits: {}", history.len());
Ok(())
}
use xfiles::*;
#[tokio::main]
async fn main() -> Result<()> {
let bearer_token = std::env::var("TWITTER_BEARER_TOKEN")?;
// Connect with real Twitter API
let mut fs = XFS::connect("@myagent", &bearer_token).await?;
// Create file (posts root tweet)
let mut file = fs.open("agent_memory.txt", OpenMode::Create).await?;
// Write content (posts reply tweet)
file.write(b"Day 1: Agent initialized").await?;
// Read it back (fetches from Twitter)
let content = file.read().await?;
println!("Content: {}", String::from_utf8_lossy(&content));
println!("Tweet URL: https://twitter.com/i/web/status/{}", file.head());
Ok(())
}
use xfiles::*;
#[tokio::main]
async fn main() -> Result<()> {
let bearer_token = std::env::var("TWITTER_BEARER_TOKEN")?;
let mut fs = XFS::connect("@myagent", &bearer_token).await?;
// Create multiple files
let mut memory = fs.open("agent/memory.json", OpenMode::Create).await?;
let mut log = fs.open("agent/debug.log", OpenMode::Create).await?;
// Write to different files
memory.write(br#"{"state": "active", "version": 1}"#).await?;
log.write(b"[INFO] Agent started").await?;
// List all files
let files = fs.list("agent").await?;
println!("Files in agent/: {:?}", files);
// Get full history of a file
let history = fs.history("agent/memory.json").await?;
for (i, commit) in history.iter().enumerate() {
println!("Commit {}: {} at {}",
i + 1,
commit.id,
commit.timestamp
);
}
// Check file existence
if fs.exists("agent/config.toml").await? {
println!("Config file exists");
}
Ok(())
}
The repository includes several examples demonstrating different features:
# Mock adapter example (no Twitter API needed)
cargo run --example basic
# Real Twitter API example (requires credentials)
export TWITTER_BEARER_TOKEN="your_token"
cargo run --example twitter_real
=== xfiles Basic Example ===
1. Creating a new file...
β Created file: memory.txt
2. Writing to file...
β Wrote initial content
3. Reading file content...
Content: Day 1: Agent initialized
4. Writing multiple updates...
β Created commit chain
5. Reading latest version...
Latest: Day 3: Successfully stored memory
6. Getting file history...
Total commits: 4
Commit 1: mock_tweet_1 (2026-01-16 12:28:15 UTC)
Commit 2: mock_tweet_2 (2026-01-16 12:28:15 UTC)
Commit 3: mock_tweet_3 (2026-01-16 12:28:15 UTC)
Commit 4: mock_tweet_4 (2026-01-16 12:28:15 UTC)
Run the test suite:
# Run all tests (uses mock adapter)
cargo test
# Run specific test suite
cargo test --test tests
# Run with output
cargo test -- --nocapture
All tests use the MockAdapter, so no Twitter API credentials are needed for testing.
Comprehensive documentation is available:
Twitter API v2 Free Tier limits:
Keybase Verification: https://keybase.io/cryptopatrick/sigs/8epNh5h2FtIX1UNNmf8YQ-k33M8J-Md4LnAN
Leave a β if you think this project is cool.
This project is licensed under MIT. See LICENSE for details.
Inspired by:
Made with β for transparent AI agents