[object Object]

← back to Axel Bitblaze Scout

initial scaffold: axel-bitblaze-scout skill (X scout for @Axel_bitblaze69 AI/Claude posts)

7e82c819e9ec218bd4924c3cfc85846a43678f4f · 2026-07-22 21:57:36 -0700 · Steve Abrams

Files touched

Diff

commit 7e82c819e9ec218bd4924c3cfc85846a43678f4f
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Wed Jul 22 21:57:36 2026 -0700

    initial scaffold: axel-bitblaze-scout skill (X scout for @Axel_bitblaze69 AI/Claude posts)
---
 .gitignore                      |   8 +++
 README.md                       |  20 ++++++
 SKILL.md                        | 133 ++++++++++++++++++++++++++++++++++++++++
 references/evaluation-rubric.md |  78 +++++++++++++++++++++++
 references/sources.md           |  72 ++++++++++++++++++++++
 scripts/gh-repo-stats.js        | 123 +++++++++++++++++++++++++++++++++++++
 scripts/hydrate-tweet.js        | 132 +++++++++++++++++++++++++++++++++++++++
 7 files changed, 566 insertions(+)

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..1924158
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,8 @@
+node_modules/
+.env*
+tmp/
+*.log
+.DS_Store
+dist/
+build/
+.next/
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..a0f1128
--- /dev/null
+++ b/README.md
@@ -0,0 +1,20 @@
+# axel-bitblaze-scout
+
+Claude Code skill that scouts Axel Bitblaze 🪓 (@Axel_bitblaze69) on X for
+Claude Code / AI-agent / local-AI tool posts, filters the account's heavy
+crypto/airdrop noise, verifies every claim against the real repo, dedupes
+against the existing skill/agent stack, and drafts gated adopt/watch/skip
+memos. Never a hype relay, never an auto-install.
+
+Live at `~/.claude/skills/axel-bitblaze-scout` (symlink into this repo).
+
+- Entry point: `SKILL.md`
+- Retrieval map + hype calibration: `references/sources.md`
+- Scoring + gating: `references/evaluation-rubric.md`
+- `scripts/hydrate-tweet.js` — X post → text/links, $0, no auth
+- `scripts/gh-repo-stats.js` — repo → stars/license/freshness (claim verification)
+
+Sibling skills: `gurisingh-scout`, `tiktok-architect`.
+
+Seeded from: https://x.com/axel_bitblaze69/status/2078551452201754980
+(the `video-use` post), 2026-07-22.
diff --git a/SKILL.md b/SKILL.md
new file mode 100644
index 0000000..ab4de4c
--- /dev/null
+++ b/SKILL.md
@@ -0,0 +1,133 @@
+---
+name: axel-bitblaze-scout
+description: Scout the Claude Code / AI-agent / local-AI tool and workflow posts that Axel Bitblaze 🪓 (@Axel_bitblaze69) publishes on X, filter out the account's heavy crypto/airdrop noise, VERIFY every claim (star counts, "free", capabilities) against the real repo, dedupe against Steve's existing stack, score fit/leverage/trust with a hype discount, and draft gated adopt/codify memos. Use when Steve says "axel bitblaze", "/axel-bitblaze-scout", "what is axel posting", "scout axel's feed", drops an x.com/axel_bitblaze69 link and asks what it is and whether to adopt it, or wants Axel's AI tool picks evaluated. Retrieval survives the X auth wall via mirror fan-out (unrollnow, rattibha, vanlett, vibepicked, syndication endpoint).
+---
+
+# Axel Bitblaze Scout
+
+## Overview
+
+Axel Bitblaze (@Axel_bitblaze69, ~128K followers, ~11 posts/day since 2015) is
+a high-volume X account that historically posted crypto/airdrop alpha and now
+posts a steady stream of **Claude Code workflows, MCP tools, local-AI stacks,
+and agent side-hustles** — e.g. the Claude Code + NotebookLM + Obsidian
+research pipeline, the `video-use` transcript-first video editor, Higgsfield
+MCP real-estate packages, Mac-hardware-for-AI guides.
+
+The signal is real but the delivery is engagement-farmed: round-number star
+counts, "X matches a 685B model", "$8–15k more a year" — every number is a
+CLAIM until verified. This skill harvests the AI posts, drops the crypto,
+verifies the claims against the actual repos, and turns survivors into
+**adopt / watch / skip** decisions for Steve's stack. Never a hype relay,
+never an auto-install.
+
+Sibling skills: `gurisingh-scout` (tool-drop educator), `tiktok-architect`
+(rules/tips educator). Same gates, same rubric family — this one adds the
+noise filter and hype discount that Axel's feed specifically needs.
+
+## When to use
+
+- Periodic sweep: "what has Axel posted lately that's worth adopting?"
+- One-off: Steve drops an `x.com/axel_bitblaze69/status/<id>` link.
+- Cross-check: another scout or the idea-loop surfaces a tool that Axel also
+  covered — pull his write-up as one more (low-trust) source.
+
+## Workflow
+
+### 1. Retrieve (fan out — X is auth-walled)
+
+Direct X reads fail unauthenticated. Follow `references/sources.md` for the
+full mirror map. The proven order:
+
+```bash
+node scripts/hydrate-tweet.js <tweet-id-or-url>   # $0, syndication endpoint; exit 3 = tombstone
+```
+
+- Per-thread mirror: `https://www.unrollnow.com/status/<tweet-id>` (best —
+  serves full thread text, verified working 2026-07).
+- Profile archives: `en.rattibha.com/Axel_bitblaze69`,
+  `vanlett.com/Axel_bitblaze69` (includes reposts), and
+  `vibepicked.com/builder/@Axel_bitblaze69/` (his own built projects).
+- Discovery of NEW posts: Exa search (`mcp__exa__web_search_exa`) scoped to
+  the handle — metered, show the cost.
+- `threadreaderapp.com` is login-walled as of 2026-07 — deprioritize.
+
+### 2. Classify — the noise filter (Axel-specific, do this FIRST)
+
+Bucket every post before spending any verification effort:
+
+| Bucket | Examples | Action |
+|---|---|---|
+| `ai-claude` | Claude Code skills/workflows, MCP servers, subagent patterns | Proceed |
+| `ai-general` | Ollama/local models, ChatGPT agent mode, AI hardware guides | Proceed |
+| `hustle-promo` | "make $X with this AI side hustle" framing around a real tool | Proceed, but strip the income claims — evaluate only the tool |
+| `crypto` | airdrops, trading bots, token threads, Telegram-channel funnels | SKIP silently — never surfaces in output |
+
+Reposts: credit the ORIGINAL author, and note whether that account merits its
+own scout entry in `references/sources.md`.
+
+### 3. Extract + verify (claims are claims)
+
+For each surviving post capture: tool name, repo URL (resolve `t.co`), what
+it claims to do, and the specific verifiable claims (stars, license, "free",
+capabilities). Then verify:
+
+```bash
+node scripts/gh-repo-stats.js <github-url-or-owner/repo>   # $0; GITHUB_TOKEN raises rate limit
+```
+
+Compare claimed vs. actual stars/license/freshness. A claim that misses by
+>2x (e.g. "17,000 stars" on a 900-star repo) is itself a trust signal —
+record the delta in the output.
+
+### 4. Dedupe against Steve's existing kit
+
+```bash
+ls ~/.claude/skills/ | grep -i "<keyword>"
+grep -ril "<capability>" ~/.claude/skills/*/SKILL.md 2>/dev/null
+```
+
+Steve has 400+ skills and a full agent cabinet. Video editing → `hyperframes`
+family; research pipelines → `last30`, `deep-research`, `web-extract`,
+`knowledge-layer`; local models → Ollama fleet + `prism`. If an equivalent
+exists, the useful output is a **diff**, not a redundant recommend.
+
+### 5. Score & decide
+
+Apply `references/evaluation-rubric.md` — the six-dimension family rubric
+(stack fit, novelty, leverage, install cost, trust/license, safety) with two
+Axel modifiers: **Trust caps at 2/3 unless independently verified** (the
+account's crypto-shill history and hype style earn a standing discount), and
+**income/performance claims score 0 weight** (evaluate the tool, not the
+pitch). Verdict bands: **≥14 ADOPT · 9–13 WATCH · ≤8 SKIP.**
+
+### 6. Deliver — shortlist + gated memos
+
+Ranked table: `Tool | Repo (claimed vs actual stars, license, last-push) |
+What it does | Bucket | Dedupe | Score | Verdict | 1-line reason`. For each
+**ADOPT**, draft a memo to `~/.claude/yolo-queue/pending-approval/` with what
+it is, why it fits, exact install steps, **cost** (always show — scripts are
+`$0 local`, Exa discovery is metered), risks, and an APPROVE/REVISE/BLOCK line.
+
+## Hard rules
+
+- **Never auto-install.** Cloning, `/plugin install`, `npx` on unfamiliar
+  code, pasting into `~/.claude`, new paid keys — all gated to
+  pending-approval. The deliverable is a decision-ready shortlist.
+- **Crypto bucket never surfaces.** No airdrop/trading content in output,
+  even as "interesting" — it's outside every mandate Steve has.
+- **Every number is a claim until `gh-repo-stats.js` confirms it.** Report
+  claimed-vs-actual deltas; never relay Axel's figures as fact.
+- **A mirror failure ≠ "nothing new"** — fan out before concluding quiet.
+- **Show costs** every run; **log real wins only** (an adopted pick, not a scan).
+
+## Resources
+
+- `scripts/hydrate-tweet.js` — one X post → verbatim text + links, no auth,
+  `$0` (local syndication token). Exit 3 on tombstone.
+- `scripts/gh-repo-stats.js` — repo → stars/license/freshness/Claude-skill
+  detection; the claim-verification backbone.
+- `references/sources.md` — handle profile, mirror map with verified status,
+  noise profile, repost-source ledger, seed-post record.
+- `references/evaluation-rubric.md` — the six dimensions, Axel trust
+  modifiers, dedupe procedure, gating, output shape.
diff --git a/references/evaluation-rubric.md b/references/evaluation-rubric.md
new file mode 100644
index 0000000..fc0def8
--- /dev/null
+++ b/references/evaluation-rubric.md
@@ -0,0 +1,78 @@
+# Evaluation rubric — should Steve actually adopt this?
+
+Same six-dimension family rubric as `gurisingh-scout`, with Axel-specific
+modifiers layered on. Score each candidate 0–3 per dimension, 18 max.
+
+## Dimensions
+
+1. **Stack fit (0–3)** — does it serve something Steve actually runs? High:
+   Claude Code skills/subagents/hooks, MCP servers, catalog/scraper/pricing
+   tooling, cost/observability, marketing/social automation, DW commerce,
+   directory builders, video pipelines. Low: generic boilerplate, crypto,
+   anything with no path into his workflow.
+2. **Novelty vs. existing kit (0–3)** — 3 = fills a real gap; 0 = an
+   equal-or-better skill/agent already exists. Run the dedupe check first.
+3. **Leverage (0–3)** — measurable hours back or revenue unlocked, not
+   "feels productive". Axel's income projections do NOT count as evidence.
+4. **Install/run cost (0–3, higher = cheaper)** — 3 = one paste, local, no
+   new paid API; 0 = heavy infra, new metered API, or a rewrite. Estimate
+   from the repo README, never from the tweet's "2 minutes" framing.
+5. **Trust & license (0–3)** — stars/traction (ACTUAL, from
+   `gh-repo-stats.js`), license present, recently maintained, no security
+   smell. Unlicensed + unmaintained caps at 1.
+6. **Safety/gating exposure (0–3, higher = safer)** — 3 = read-only/local,
+   no secrets; 0 = wants prod creds, sends outbound, or auto-executes. Low
+   scores route to pending-approval, they don't auto-kill.
+
+**Verdict bands:** ≥14 → **ADOPT** (draft the install memo). 9–13 → **WATCH**
+(log, revisit on traction). ≤8 → **SKIP** (one-line why).
+
+## Axel modifiers (applied after base scoring)
+
+- **Trust discount:** dimension 5 caps at **2/3** when the only evidence is
+  Axel's own post. The cap lifts only when an independent source (repo
+  metrics, a second educator, hands-on test) confirms the core claim. Reason:
+  the account's engagement-farming style and crypto-shill history mean its
+  claims systematically overshoot.
+- **Claim-delta flag:** if a verifiable claim (stars, "free", capability)
+  misses reality by >2x, note it in the output row AND subtract 1 from
+  dimension 5. Repeated deltas across sweeps should be recorded in
+  `references/sources.md` under Hype calibration.
+- **Income claims are weightless:** "$X/year side hustle" framing
+  contributes nothing to Leverage. Score leverage from what the tool does
+  for Steve's actual businesses.
+
+## Dedupe procedure (before scoring novelty)
+
+```bash
+ls ~/.claude/skills/ | grep -i "<keyword>"
+grep -ril "<capability keyword>" ~/.claude/skills/*/SKILL.md 2>/dev/null
+```
+
+Also sanity-check the agent cabinet (`~/Projects/agent-cabinet/cabinet.yaml`)
+and CNCP. Known equivalents: video creation → `hyperframes` family; research
+→ `last30`, `deep-research`, `web-extract`, `knowledge-layer`; cost →
+`cost-tracker`; model evaluation → `ollama-model-eval`; browser automation →
+`dev-browser`, `browserbase`, `crawl4ai`. If an equivalent exists, output the
+**diff** ("video-use edits raw footage off a transcript; hyperframes composes
+from scratch — no overlap on ingest"), not a redundant recommend.
+
+## Gating — what the scout may and may NOT do
+
+Discovery, retrieval, enrichment, scoring, and the shortlist run freely
+(reversible, read-only). Everything that changes Steve's machine or spends is
+gated — draft to `~/.claude/yolo-queue/pending-approval/` with an
+APPROVE/REVISE/BLOCK block; never auto-run:
+
+- Installing a skill/plugin (`git clone`, `/plugin install`, paste into `~/.claude`).
+- `npx`/running unfamiliar code that executes or reads `~/.claude`.
+- Anything needing a new paid API key or that spends.
+- Anything the tool itself does that is customer-facing/destructive/outbound.
+
+## Output shape (per run)
+
+Ranked table: `Tool | Repo (claimed vs actual stars, license, last-push) |
+What it does | Bucket | Dedupe (have/gap) | Score | Verdict | 1-line reason`.
+Then per ADOPT: a pending-approval memo — what it is, why it fits, exact
+install steps, cost, risks, APPROVE/REVISE/BLOCK. Log genuine wins (an
+adopted pick), never the scan itself.
diff --git a/references/sources.md b/references/sources.md
new file mode 100644
index 0000000..850f927
--- /dev/null
+++ b/references/sources.md
@@ -0,0 +1,72 @@
+# Sources — Axel Bitblaze retrieval map
+
+## The account
+
+| Field | Value |
+|---|---|
+| Handle | `@Axel_bitblaze69` |
+| Display | Axel Bitblaze 🪓 |
+| Bio | "Low iq idiot. I know nothing. Telegram: @Axelbitblaze" (self-deprecating shtick; the Telegram is a crypto-alpha funnel — ignore it) |
+| Followers | ~128K (2026-07) |
+| Volume | ~46.7K lifetime posts, ~11/day — a firehose; sweep by recency window, never "read everything" |
+| Joined | April 2015 |
+| History | 2015–2025: crypto/airdrop/trading alpha threads. 2026→: heavy pivot to Claude Code, MCP, local AI, agent side-hustles. Both streams still run concurrently. |
+
+## Mirror map (X itself is auth-walled — WebFetch/Exa on x.com fails)
+
+Ordered by usefulness; "verified" = actually returned content on 2026-07-22.
+
+1. **`scripts/hydrate-tweet.js <id-or-url>`** — $0, no auth, computes the
+   syndication token locally. First stop for any specific tweet ID. Exit 3 =
+   tombstone (deleted/suspended) → fall through to mirrors.
+2. **unrollnow** — `https://www.unrollnow.com/status/<tweet-id>` — VERIFIED.
+   Full thread text, works within minutes of posting. Best per-thread mirror.
+3. **rattibha** — `https://en.rattibha.com/Axel_bitblaze69` — VERIFIED.
+   Profile-level thread archive with engagement counts; good for sweeps.
+4. **vanlett** — `https://vanlett.com/Axel_bitblaze69` — VERIFIED. Profile
+   mirror that includes REPOSTS (rattibha mostly doesn't) — the only mirror
+   that shows what he amplifies vs. authors.
+5. **vibepicked** — `https://vibepicked.com/builder/@Axel_bitblaze69/` —
+   VERIFIED. Catalogs projects he built (with tools used, e.g. "Claude Code ·
+   NotebookLM · Obsidian · skill-creator · yt-dlp"). Highest-signal page per
+   byte: these are things he actually shipped, not just promoted.
+6. **Exa search** — `mcp__exa__web_search_exa` with the handle in the query —
+   METERED (~$0.005/search, show cost). Use for discovering new posts when
+   the profile mirrors lag.
+7. ~~threadreaderapp~~ — login-walled as of 2026-07. Skip unless others fail.
+
+## Noise profile (why the classifier exists)
+
+Rough historical mix: crypto/airdrop ≥ 60%, AI/Claude ~30%, misc ~10%. The
+crypto stream is monetized (Telegram funnel, "like & RT" engagement bait) and
+entirely out of scope. Never let a sweep's output mention it.
+
+## Hype calibration
+
+Observed claim patterns to always verify, never relay:
+- Round star counts ("17,000 stars on GitHub") — check `gh-repo-stats.js`.
+- Model-equivalence claims ("a 26B model matching 685B models") — discard;
+  benchmark claims from this account carry zero weight (see
+  `ollama-model-eval` for how Steve actually evaluates models).
+- Income projections ("$8–15k more a year") — strip; evaluate the tool only.
+- "Setup takes 2 minutes" — treat as marketing; estimate install cost from
+  the repo README, not the tweet.
+
+## Repost-source ledger
+
+Accounts Axel amplifies whose original content scored well — candidates for
+their own scout coverage. Append as found:
+
+- (none yet)
+
+## Seed post (the one that created this skill)
+
+- `https://x.com/axel_bitblaze69/status/2078551452201754980` (2026-07-23) —
+  promotes **video-use**: open-source Claude Code video-editing skill;
+  claims 17K GitHub stars, transcript-first editing (cuts filler words /
+  dead space), ffmpeg color-grade chains, editor sub-agents, plan-approval
+  before cutting. Repo link was in a trailing t.co not captured by the
+  mirror. **Claims unverified as of skill creation** — first sweep should
+  resolve the repo and run it through the rubric. Dedupe note: Steve's
+  `hyperframes` family owns video *creation*; transcript-driven *editing of
+  raw footage* is a plausible real gap.
diff --git a/scripts/gh-repo-stats.js b/scripts/gh-repo-stats.js
new file mode 100755
index 0000000..3ca5006
--- /dev/null
+++ b/scripts/gh-repo-stats.js
@@ -0,0 +1,123 @@
+#!/usr/bin/env node
+/**
+ * gh-repo-stats.js — turn a GitHub repo link into hard adoption signals.
+ *
+ * Guri Singh's posts almost always point at an open-source repo. Before scoring
+ * whether it's worth adopting, resolve the objective facts: popularity, license,
+ * how recently it was touched, primary language, archived/stale status, and —
+ * critically for us — whether it is literally a Claude Code skill/plugin
+ * (SKILL.md, .claude/, plugin manifest) versus a general CLI/tool.
+ *
+ * Usage:
+ *   node gh-repo-stats.js <github-url-or-owner/repo>
+ *
+ * Auth: unauthenticated works (60 req/hr). Set GITHUB_TOKEN in env to raise the
+ * limit to 5000/hr — the script reads it automatically if present.
+ *
+ * Exit codes: 0 ok, 1 error (bad input / not found / network).
+ * Output: JSON summary on stdout.
+ */
+
+'use strict';
+
+function parseRepo(arg) {
+  if (!arg) return null;
+  const m = String(arg).match(/github\.com\/([A-Za-z0-9._-]+)\/([A-Za-z0-9._-]+)/);
+  if (m) return { owner: m[1], repo: m[2].replace(/\.git$/, '') };
+  const slug = String(arg).match(/^([A-Za-z0-9._-]+)\/([A-Za-z0-9._-]+)$/);
+  if (slug) return { owner: slug[1], repo: slug[2] };
+  return null;
+}
+
+function ghHeaders() {
+  const h = {
+    'User-Agent': 'gurisingh-scout',
+    Accept: 'application/vnd.github+json',
+  };
+  const tok = process.env.GITHUB_TOKEN || process.env.GH_TOKEN;
+  if (tok) h.Authorization = `Bearer ${tok}`;
+  return h;
+}
+
+async function gh(url) {
+  const res = await fetch(url, { headers: ghHeaders() });
+  if (res.status === 404) return { __status: 404 };
+  if (res.status === 403) return { __status: 403, __rate: res.headers.get('x-ratelimit-remaining') };
+  if (!res.ok) throw new Error(`http ${res.status} ${url}`);
+  return res.json();
+}
+
+function daysSince(iso) {
+  if (!iso) return null;
+  return Math.round((Date.now() - new Date(iso).getTime()) / 86400000);
+}
+
+async function main() {
+  const parsed = parseRepo(process.argv[2]);
+  if (!parsed) {
+    console.error('usage: node gh-repo-stats.js <github-url-or-owner/repo>');
+    process.exit(1);
+  }
+  const { owner, repo } = parsed;
+
+  let meta;
+  try {
+    meta = await gh(`https://api.github.com/repos/${owner}/${repo}`);
+  } catch (e) {
+    console.error(`error: ${e.message}`);
+    process.exit(1);
+  }
+  if (meta.__status === 404) {
+    console.error(`not found: ${owner}/${repo}`);
+    process.exit(1);
+  }
+  if (meta.__status === 403) {
+    console.error(`rate-limited (remaining=${meta.__rate}). Set GITHUB_TOKEN to raise the limit.`);
+    process.exit(1);
+  }
+
+  // Root listing → detect "is this a Claude skill/plugin?" (one extra call).
+  let isClaudeSkill = false;
+  let claudeMarkers = [];
+  try {
+    const contents = await gh(`https://api.github.com/repos/${owner}/${repo}/contents`);
+    if (Array.isArray(contents)) {
+      const names = contents.map((c) => c.name.toLowerCase());
+      const markers = ['skill.md', '.claude', 'skills', 'plugin.json', '.claude-plugin', 'commands', 'agents'];
+      claudeMarkers = markers.filter((m) => names.includes(m));
+      isClaudeSkill = names.includes('skill.md') || names.includes('.claude') ||
+        names.includes('.claude-plugin') ||
+        (names.includes('skills') && (names.includes('plugin.json') || names.includes('.claude-plugin')));
+    }
+  } catch {
+    /* non-fatal — leave detection empty */
+  }
+
+  const daysStale = daysSince(meta.pushed_at);
+  const out = {
+    repo: `${owner}/${repo}`,
+    url: meta.html_url,
+    description: meta.description,
+    stars: meta.stargazers_count,
+    forks: meta.forks_count,
+    open_issues: meta.open_issues_count,
+    language: meta.language,
+    license: meta.license ? meta.license.spdx_id : 'NONE',
+    pushed_at: meta.pushed_at,
+    days_since_push: daysStale,
+    archived: meta.archived,
+    is_claude_skill: isClaudeSkill,
+    claude_markers: claudeMarkers,
+    // quick, opinionated flags to feed the adoption rubric
+    flags: {
+      unlicensed: !meta.license,
+      stale: daysStale != null && daysStale > 120,
+      archived: !!meta.archived,
+      low_traction: meta.stargazers_count < 50,
+    },
+  };
+  console.log(JSON.stringify(out, null, 2));
+  process.exit(0);
+}
+
+main();
diff --git a/scripts/hydrate-tweet.js b/scripts/hydrate-tweet.js
new file mode 100755
index 0000000..f119c95
--- /dev/null
+++ b/scripts/hydrate-tweet.js
@@ -0,0 +1,132 @@
+#!/usr/bin/env node
+/**
+ * hydrate-tweet.js — resolve a single X/Twitter post to plain text WITHOUT auth.
+ *
+ * X blocks unauthenticated page reads (WebFetch → HTTP 402), so this uses the
+ * public syndication endpoint that powers embedded tweets. The endpoint needs a
+ * `token` that is a deterministic function of the tweet id — we compute it
+ * locally ($0), so no API key and no login are ever required.
+ *
+ * Usage:
+ *   node hydrate-tweet.js <tweet-id-or-url>
+ *
+ * Examples:
+ *   node hydrate-tweet.js 2055557527153332556
+ *   node hydrate-tweet.js https://x.com/heygurisingh/status/2055557527153332556
+ *
+ * Exit codes:
+ *   0  ok — printed tweet JSON summary
+ *   3  tombstone — tweet/account is suspended, deleted, or age-gated (unreadable)
+ *   1  error — bad input or network/parse failure
+ *
+ * Output: a JSON object on stdout:
+ *   { id, url, author, created_at, text, urls[], github[] }
+ * On tombstone: { id, tombstone: "<reason text>" } and exit 3.
+ */
+
+'use strict';
+
+function extractId(arg) {
+  if (!arg) return null;
+  // trailing run of digits handles both bare ids and .../status/<id>[?query]
+  const m = String(arg).match(/(\d{5,25})/g);
+  return m ? m[m.length - 1] : null;
+}
+
+// react-tweet's documented token derivation: (id / 1e15 * PI) in base-36,
+// with zeros and the dot stripped. Verified against live tweets 2026-07.
+function syndicationToken(id) {
+  return ((Number(id) / 1e15) * Math.PI)
+    .toString(36)
+    .replace(/(0+|\.)/g, '');
+}
+
+function findGithub(text, urls) {
+  const found = new Set();
+  const scan = (s) => {
+    if (!s) return;
+    const re = /https?:\/\/(?:www\.)?github\.com\/[A-Za-z0-9._-]+\/[A-Za-z0-9._-]+/g;
+    let m;
+    while ((m = re.exec(s))) found.add(m[0].replace(/[.,)]+$/, ''));
+  };
+  scan(text);
+  (urls || []).forEach(scan);
+  return [...found];
+}
+
+async function main() {
+  const id = extractId(process.argv[2]);
+  if (!id) {
+    console.error('usage: node hydrate-tweet.js <tweet-id-or-url>');
+    process.exit(1);
+  }
+
+  const token = syndicationToken(id);
+  const endpoint =
+    `https://cdn.syndication.twimg.com/tweet-result?id=${id}&lang=en&token=${token}`;
+
+  let res;
+  try {
+    res = await fetch(endpoint, {
+      headers: {
+        // a browser-ish UA avoids the occasional bot 403 on this endpoint
+        'User-Agent':
+          'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 ' +
+          '(KHTML, like Gecko) Chrome/125.0 Safari/537.36',
+        Accept: 'application/json',
+      },
+    });
+  } catch (e) {
+    console.error(`network error: ${e.message}`);
+    process.exit(1);
+  }
+
+  if (res.status === 404) {
+    console.log(JSON.stringify({ id, tombstone: 'not found (404)' }, null, 2));
+    process.exit(3);
+  }
+  if (!res.ok) {
+    console.error(`http ${res.status} from syndication endpoint`);
+    process.exit(1);
+  }
+
+  let data;
+  try {
+    data = await res.json();
+  } catch (e) {
+    console.error(`parse error: ${e.message}`);
+    process.exit(1);
+  }
+
+  // Tombstone shapes: suspended/deleted/age-gated tweets come back as a
+  // __typename of TweetTombstone (or an object with a `tombstone` field).
+  const tomb =
+    data.__typename === 'TweetTombstone' ||
+    data.tombstone ||
+    (data.text && /suspended account|Post is from a suspended|isn.?t available/i.test(data.text) && !data.user);
+  if (tomb) {
+    const reason =
+      (data.tombstone && (data.tombstone.text?.text || data.tombstone.text)) ||
+      data.text ||
+      'unavailable (suspended / deleted / age-gated)';
+    console.log(JSON.stringify({ id, tombstone: reason }, null, 2));
+    process.exit(3);
+  }
+
+  const urls = (data.entities?.urls || []).map((u) => u.expanded_url || u.url);
+  const out = {
+    id,
+    url: `https://x.com/${data.user?.screen_name || 'i'}/status/${id}`,
+    author: data.user
+      ? `@${data.user.screen_name} (${data.user.name})`
+      : null,
+    created_at: data.created_at || null,
+    text: data.text || '',
+    urls,
+    github: findGithub(data.text || '', urls),
+  };
+  console.log(JSON.stringify(out, null, 2));
+  process.exit(0);
+}
+
+main();

(oldest)  ·  back to Axel Bitblaze Scout  ·  resolve seed post repo: browser-use/video-use 17.5k stars MI 17a5b2c →