Trending-skills fieldtheory-cli-bookmarks
Sync, search, classify, and query X/Twitter bookmarks locally using the Field Theory CLI
install
source · Clone the upstream repo
git clone https://github.com/Aradotso/trending-skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/Aradotso/trending-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/fieldtheory-cli-bookmarks" ~/.claude/skills/aradotso-trending-skills-fieldtheory-cli-bookmarks && rm -rf "$T"
manifest:
skills/fieldtheory-cli-bookmarks/SKILL.mdsource content
Field Theory CLI — X/Twitter Bookmark Manager
Skill by ara.so — Daily 2026 Skills collection.
Field Theory CLI (
ft) syncs all your X/Twitter bookmarks locally, indexes them for full-text search, classifies them by category and domain, and exposes them to AI agents via shell commands. No official API required for the default sync mode.
Installation
npm install -g fieldtheory
Requirements:
- Node.js 20+
- Google Chrome (logged into X/Twitter) for default sync mode
- macOS for Chrome session sync; Linux/Windows use OAuth mode
Verify installation:
ft --version ft status
Quick Start
# Sync bookmarks (reads Chrome session automatically) ft sync # Search immediately ft search "machine learning" # Explore with terminal dashboard ft viz
Data is stored at
~/.ft-bookmarks/ by default.
Core Commands
Syncing
# Incremental sync (new bookmarks only) ft sync # Sync then auto-classify with LLM ft sync --classify # Full history crawl from the beginning ft sync --full # Sync via OAuth API (cross-platform, no Chrome needed) ft sync --api # Show sync status ft status
Searching
# Full-text BM25 search ft search "distributed systems" ft search "rust async runtime" ft search "cancer immunotherapy" # Filter results ft list --author elonmusk ft list --category tool ft list --domain ai ft list --since 2024-01-01 ft list --category research --domain biology # Show a single bookmark by ID ft show 1234567890
Classification
# LLM-powered classification (requires LLM access) ft classify # Regex-based classification (no LLM needed, faster) ft classify --regex # Rebuild search index (preserves existing classifications) ft index
Exploration & Stats
# Terminal dashboard with sparklines and charts ft viz # Category distribution ft categories # Subject domain distribution ft domains # Top authors, languages, date range ft stats # Print data directory path ft path
Media
# Download static images from bookmarks ft fetch-media
OAuth Setup (Cross-Platform / API Mode)
# Interactive OAuth setup ft auth # Then sync via API ft sync --api
OAuth token stored at
~/.ft-bookmarks/oauth-token.json with chmod 600.
Configuration
Custom Data Directory
# Set in shell profile (~/.zshrc or ~/.bashrc) export FT_DATA_DIR=/path/to/custom/dir # Or per-command FT_DATA_DIR=/Volumes/external/bookmarks ft sync
Data File Layout
~/.ft-bookmarks/ bookmarks.jsonl # raw bookmarks, one JSON object per line bookmarks.db # SQLite FTS5 search index bookmarks-meta.json # sync cursor and metadata oauth-token.json # OAuth credentials (API mode only)
Scheduling Sync
Add to crontab (
crontab -e):
# Sync every morning at 7am 0 7 * * * ft sync # Sync and classify every morning at 7am 0 7 * * * ft sync --classify # Full sync every Sunday at midnight 0 0 * * 0 ft sync --full
Categories Reference
| Category | Description |
|---|---|
| GitHub repos, CLI tools, npm packages, open-source |
| CVEs, vulnerabilities, exploits, supply chain |
| Tutorials, demos, code patterns, how-to threads |
| Product launches, announcements, "just shipped" |
| ArXiv papers, studies, academic findings |
| Takes, analysis, commentary, threads |
| Products, shopping, physical goods |
Working with Bookmark Data (TypeScript/Node.js)
The
bookmarks.jsonl file can be consumed directly in scripts:
import { createReadStream } from "fs"; import { createInterface } from "readline"; import { homedir } from "os"; import { join } from "path"; interface Bookmark { id: string; text: string; author: string; created_at: string; url: string; category?: string; domain?: string; media?: string[]; } async function loadBookmarks(): Promise<Bookmark[]> { const dataDir = process.env.FT_DATA_DIR ?? join(homedir(), ".ft-bookmarks"); const filePath = join(dataDir, "bookmarks.jsonl"); const bookmarks: Bookmark[] = []; const rl = createInterface({ input: createReadStream(filePath), crlfDelay: Infinity, }); for await (const line of rl) { if (line.trim()) { bookmarks.push(JSON.parse(line)); } } return bookmarks; } // Usage const bookmarks = await loadBookmarks(); const tools = bookmarks.filter((b) => b.category === "tool"); console.log(`Found ${tools.length} tool bookmarks`);
Query SQLite Index Directly
import Database from "better-sqlite3"; import { join } from "path"; import { homedir } from "os"; const dataDir = process.env.FT_DATA_DIR ?? join(homedir(), ".ft-bookmarks"); const db = new Database(join(dataDir, "bookmarks.db"), { readonly: true }); // Full-text search using SQLite FTS5 function searchBookmarks(query: string, limit = 20) { const stmt = db.prepare(` SELECT id, text, author, created_at, category, domain FROM bookmarks WHERE bookmarks MATCH ? ORDER BY rank LIMIT ? `); return stmt.all(query, limit); } // Filter by category function getByCategory(category: string) { const stmt = db.prepare(` SELECT * FROM bookmarks WHERE category = ? ORDER BY created_at DESC `); return stmt.all(category); } const results = searchBookmarks("transformer architecture"); console.log(results);
Shell Integration in Agent Scripts
import { execSync } from "child_process"; // Run ft commands from Node.js function ftSearch(query: string): string { return execSync(`ft search "${query}"`, { encoding: "utf8" }); } function ftList(options: { category?: string; since?: string; author?: string }) { const flags = [ options.category ? `--category ${options.category}` : "", options.since ? `--since ${options.since}` : "", options.author ? `--author ${options.author}` : "", ] .filter(Boolean) .join(" "); return execSync(`ft list ${flags}`, { encoding: "utf8" }); } // Example: find AI memory tools bookmarked this year const memoryTools = ftSearch("AI memory"); const recentTools = ftList({ category: "tool", since: "2025-01-01" });
Agent Integration Patterns
Tell your AI agent to use
ft directly in natural language:
"Search my bookmarks for distributed tracing tools and summarize the top 5." "Sync any new X bookmarks, then list all research papers from 2025." "Find everything I've bookmarked about Rust and categorize it by subtopic." "Every morning, run ft sync --classify to keep my bookmarks up to date."
Claude Code example prompt:
Use the `ft` CLI to search my bookmarks for "vector database" and pick the best open-source option to add to this project. Run: ft search "vector database" --category tool
Troubleshooting
Chrome session not found
# Ensure Chrome is open and logged into X # Then retry ft sync # If Chrome session still fails, use OAuth mode ft auth ft sync --api
Sync stalls or returns 0 bookmarks
# Check sync status and metadata ft status # Force full re-crawl ft sync --full # Check data directory permissions ls -la ~/.ft-bookmarks/
Search returns no results
# Rebuild the search index ft index # Verify bookmarks exist ft stats wc -l ~/.ft-bookmarks/bookmarks.jsonl
Classification not running
# LLM classify requires an LLM — use regex fallback ft classify --regex # Or sync with regex classify ft sync --classify --regex
Reset all data
rm -rf ~/.ft-bookmarks ft sync
Custom data directory issues
# Confirm the env var is set echo $FT_DATA_DIR ft path # Ensure directory is writable mkdir -p "$FT_DATA_DIR" chmod 755 "$FT_DATA_DIR"
Security Notes
- All data is local only — no telemetry or external calls except to X during sync
- Chrome cookies are read temporarily for sync and never stored separately
- OAuth token is stored
— treat it like a passwordchmod 600 - Default sync uses X's internal GraphQL API (same as browser);
uses official v2 API--api
Platform Support
| Feature | macOS | Linux | Windows |
|---|---|---|---|
(Chrome session) | ✅ | ❌ | ❌ |
(OAuth) | ✅ | ✅ | ✅ |
| Search, classify, viz | ✅ | ✅ | ✅ |
Linux/Windows users must run
ft auth first, then use ft sync --api.
Resources
- Homepage: fieldtheory.dev/cli
- Repository: github.com/afar1/fieldtheory-cli
- License: MIT