Repository navigation
Add birdclaw import x-json for saved X API v2 tweet JSON - #252
TheAngryPit wants to merge 1 commit into
Conversation
Ingest XurlTweetsResponse documents from a file or stdin with strict validation, x-json provenance, and idempotent import counts.
|
🦞👀 Pull request received. I will update this pull request when review starts. ClawSweeper review completeClawSweeper finished reviewing this revision. The review result is being finalized. |
|
Codex review: blocked before merge. What this changesAdds a file and stdin command for importing saved X API v2 tweet responses into local storage and search. Example: Import a saved response containing tweet 880001 with text "synth needle alpha".
Review scores
ProductKind: Feature · Worth it: Needs a maintainer decision · Fix scope: Complete Merge readiness⛔ Blocked before merge - 6 items remain Keep this PR open: it adds a useful missing import path, but needs correctness repairs and an owner decision about home-timeline membership. Priority: P3 Decision needed
Before merge
Findings
Tests
Agent review detailsHow this fits togetherThe CLI reads saved JSON, validates documents, and passes them to canonical tweet ingestion, which writes SQLite records, search indexes, provenance, and account edges. flowchart LR
A[File or stdin] --> B[Import command]
B --> C[Document validation]
C --> D[Canonical ingestion]
D --> E[SQLite and search indexes]
E --> F[Local tweet search]
B --> G[Configured backup sync]
Technical reviewBest possible solution: Provide offline import through canonical ingestion with accurate results, isolated document failures, and explicitly approved search and membership semantics. Do we have a high-confidence way to reproduce the issue? Source inspection establishes the missing main-branch entry point and the reported patch defects; no target code or tests were run during this read-only review. Is this the best way to solve the issue? Reusing canonical ingestion is appropriate, but the importer must validate its untrusted input boundary and obtain agreement on how imported posts become searchable. Full review comments:
Overall correctness: patch is incorrect AGENTS.md: not found in the target repository. Codex review notes: model internal, reasoning medium; reviewed against a08c264c88b2. Provenance checked
TestingProof path: shipped entry point. SecurityNone. EvidenceWhat I checked:
Root-cause clusterRelationship: Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. LabelsLabel changes:
Label justifications:
Rating scale6/6 🦀 challenger crab · 5/6 🦞 diamond lobster · 4/6 🐚 platinum hermit · 3/6 🦐 gold shrimp · 2/6 🦪 silver shellfish · 1/6 🧂 unranked krab. Overall follows the weaker of proof and patch quality; ✨ marks media proof (a screenshot, video, or linked artifact) that directly shows the changed behavior. WorkflowClawSweeper edits this one comment on every review. Comment Reviewed October 27, 2026, 4:13 PM ET / 20:13 UTC. |
Closes #251
Problem
Posts saved as X API v2 JSON (for example xurl output) can't be added to birdclaw without a live read. This adds an offline import for that shape.
Change
Birdclaw already turns xurl
/2/responses intoXurlTweetsResponseand stores them withingestTweetPayload. This PR adds a file and stdin entry point to that same path, instead of a parser for a new format.birdclaw import x-json [file], reading stdin when the file is-or omitted.datacan be one tweet or an array, with optionalincludes.users,includes.tweets,includes.media.errorswith their line number, valid lines still import, exit code is 1 iferrorsis not empty.publicaccount withsource = 'x-json'. Optional per-tweeturlgoes totweet_sources, as in feat: add opt-in FxTwitter tweet import #103.homeedge onpublicsosearch tweetsfinds them. FxTwitter imports don't add an edge; see the open question in Import saved X API v2 tweet JSON without a live read #251.autoSyncAfterWrite()after the import, like the other import commands.docs/public-tweets.md.What stays the same
publicaccount is created withinsert or ignoreandis_default 0if it doesn't exist yet.Behavior evidence
Built CLI at aa186ec, fresh scratch
BIRDCLAW_HOME, synthetic fixtures, Linux.import x-json single.jsongives{"imported":1,"skipped":0,"errors":[]}, exit 0cat clean.jsonl | import x-json -givesimported 2, exit 0search tweets heron3 hits,kestrel1 hitosprey0 hits, see boundaryimported 0, skipped 1; same stdin givesimported 0, skipped 2, exit 0imported 1, skipped 1, errorLine 3: invalid JSON, exit 1Line 1: tweet.author_id must be a non-empty string, exit 1tweet_sourcesrow withx-json, only accountpublicwithis_default 0Tests in
src/lib/x-json-import.test.ts(in-process SQLite):datawith provenancedatawithincludesusers, media, tweets andnote_tweetsearch tweetsGates
All
ci.ymljobs reproduced locally on Linux at aa186ec. These are not GitHub Actions runs.x-json-import.ts81.16% statementsBun 1.4.0-canary.1+f972c287f, Node 20.19.2 for the primary jobs. Playwright browsers were installed without
--with-depson this machine.Known boundary
includes.tweetsare stored but get no account edge, sosearch tweetsdoesn't return them.XurlTweetsResponsetype. This PR does not include a run on captured xurl output.urlfield is not part of X API v2. It is an optional extra for provenance.tweet_sourcesis already a backup table, sox-jsonrows should be in backups. I read that in the code; I didn't test it.