A local, read-only thinking layer over X. It helps you turn things you encounter — and ideas you already have — into short posts you actually believe, without letting a model overwrite what you thought or post anything on your behalf.
capture a post → x-brief prepares the source → you add your own thought
→ Jev ranks the interests it fits → a model drafts in your voice
→ you revise → you post it yourself
In the common case:
- You capture something while browsing X — from a post's URL, or with x-brief's optional macOS keyboard shortcut. One action stores the post locally; nothing is sent to a model at capture, and no other capture application is required.
- x-brief prepares the source. On launch it reconstructs what was missing — re-reading X's public embed, following public redirects, and, when the copy looked cut, reading a capture-time screenshot with a vision model. Anything recovered is stored beside the post with its provenance; the post's own words are never rewritten.
- You add your own thought. In
/reviewyour reaction is stored verbatim, or you can ask for a possible connection to your interests — labelled as the model's suggestion, never your opinion. - You choose a lens and get a draft. A lens is an interest Jev picks as a possible writing angle for this post. Jev ranks your interests against it and checks whether its best match is substantively supported; you confirm that lens, pick another, or write with none. The configured model then writes a candidate in your voice, from context that is selected per task, bounded and inspectable. Your own wording is never clipped.
- You revise, then decide what leaves. Ask for a change in your own words, adjust the tone for this draft, or edit directly — earlier wording is always preserved. x-brief copies the draft and opens X's own composer (or the source post); you post it and record what you published.
Ideas runs the other direction. /ideas starts from something you want to say and asks Jev
to rank your saved posts against it — where in what I've saved would saying this actually make
sense? — then writes from the idea and the post you pick, or from the idea alone.
Every stage is a durable object rather than a turn in a conversation. The captured post, your own thought, the model's suggestion, the draft and what you actually published stay distinct, with where each came from recorded — so a later task is never handed generated wording as though it were your belief or the post's own text.
Two recorded x-brief runs show the workflow end to end: the captured source, the user's own thought, Jev's proposed lens, the lens actually used, model drafts, revisions, tone controls and the wording ultimately published.
One example is heavily steered; the other uses the first draft with no per-draft tone overrides.
See the real workflow examples →
Review starts from someone else's post; Ideas starts from your own thought. They enter from opposite directions and converge on the same two engines: a decision stage that ranks your interests or saved posts before anything is written, then a writing stage that drafts only from the source you chose.
flowchart LR
R["Review<br/>a captured post"] --> J1{"Jev ranks<br/>your interests"}
I["Ideas<br/>your own thought"] --> J2{"Jev ranks<br/>your saved posts"}
J1 --> W["writer<br/>one Hermes call"]
J2 --> W
W --> Y["you: edit, revise,<br/>regenerate, record what you published"]
That separation shapes the rest of the design:
- Two stores, on purpose. SQLite holds machine state (the pool, decisions, model-call accounting, an audit trail); the Markdown vault holds your writing as plain files. The model is shown the vault — never the counters.
- A provenance model. Captured source, recovered reading, quoted material, user-authored text, model output and published wording are distinct, labelled objects. The captured body is never rewritten, and a screenshot reading can never stand in as the author's own words.
- Authorship follows action, not generation. What you write is stored verbatim and no model path can overwrite it; wording you keep from a draft stays labelled shared until you edit it yourself.
- A separate decision layer. Jev (TypeSafe System One) makes bounded
choice/score/nouldecisions and never writes; the writer never ranks, and Jev runs before any writing. Lens selection over your interests has no abstention: it always names the best available candidate and flags weak support rather than pretending it is strong. Saved-post ranking can answer no real connection and drop a post that does not fit. - Bounded, inspectable context. Every writing call records a manifest of the context classes it selected, their sources and budgets. The prompt grows with the material chosen for the task, never with the size of your vault.
- A model abstraction. Each task is a fresh, tool-less Hermes invocation with a versioned prompt file that returns validated JSON. Nothing is hard-wired to one API.
- Contained failures. A failed call never marks work delivered, never fabricates a
recommendation, and never touches your material; missing provider accounting stays
unknown, never$0.
The full description — capture, enrichment, Jev, the writing stage, storage, credential
handling, failure behaviour and the tradeoffs — is in
docs/ARCHITECTURE.md.
git clone https://github.com/rtmandreyev/x-brief.git ~/x-brief
cd ~/x-brief
./bin/xbrief install
x-brief setup
x-brief./bin/xbrief install writes the x-brief command to ~/.local/bin. If that directory is not
already on your PATH, the command says so and prints the one line to add to your shell profile —
add it and open a new terminal before continuing.
x-brief setup is the authoritative checklist: it inspects this machine, your Hermes model
configuration and the Jev credential, and tells you exactly what still needs attention. Clear the
gaps it reports — configure Hermes with hermes model and provide a Jev key as directed — and run
it again until it reports READY — everything required is configured.
From there: add a few interests and a line or two of profile for better drafts, capture a
post with x-brief add 'https://x.com/<account>/status/<id>' (or the optional macOS shortcut),
and type /review in the application to begin the main workflow. x-brief never publishes to X
— you post.
- Complete installation, step by step → docs/SETUP.md
- Personalization and tone → docs/PERSONALIZATION.md
- The daily loop → docs/WORKFLOW.md
x-brief works with an empty profile, but explicit context substantially improves its writing.
READY from setup means the required software and credentials are configured — not that the
writer already understands you. Until you add context, drafts come from generic defaults plus
whatever you have published through x-brief.
Start in the app:
/interests— the topics you want opportunities to write about now; the list Jev ranks a lens from, and the most valuable thing to fill first./profile— a few plain sentences about who you are and the standing context behind your posts./documents— every maintained Markdown file, and the fastest way to read the templates./defaults— the writing controls (length, register, how much of your own wording must survive, and the rest). They are already sensible; change the two or three that matter.
No document has to be filled. Add only the context you are comfortable sending to a configured model task, and prefer a few relevant sentences over a lot of tangential detail. Real examples of your own writing help most of all.
- Onboarding from a fresh clone, including the personalization step:
docs/SETUP.md - Every maintained document, writing control and style-example detail:
docs/PERSONALIZATION.md
Nothing in the Optional block is needed to reach your first draft; the optional items only add convenience or extra capture, recovery or collection routes.
Required
| macOS | this release targets macOS; the capture shortcut, Keychain storage and editor integration are macOS mechanisms |
| Python 3.9+ | standard library only; the launcher checks XBRIEF_PYTHON, then /usr/local/bin/python3, /opt/homebrew/bin/python3, /usr/bin/python3 |
| Git | to clone the repository |
Hermes Agent on PATH |
the AI runtime; x-brief keeps no separate model credential |
| A model/provider usable through Hermes | configured once with hermes model (any provider Hermes supports) |
| A Jev (TypeSafe) credential | for lens selection and saved-post ranking; resolved from the environment, a .env, or x-brief's own macOS Keychain item, with the legacy NODE item read only as a fallback |
Optional
| X developer app | only for the dormant scheduled-collection mode; manual capture needs none |
| A vision-capable model | to read the capture-time screenshot when a post's copy is cut |
An xAI key or the xurl CLI |
older enrichment routes that recover more of a post |
| Obsidian (or any editor) | to browse the Markdown vault — it is plain files either way |
| A macOS Services shortcut | to capture with ⌥⌘X instead of the command line |
Your captures, the Markdown vault, screenshots, the SQLite index and your style samples all stay
on your machine. External calls happen only for specific configured functions: read-only X content
retrieval for a URL you submit, Hermes model calls, and Jev decisions through TypeSafe. OAuth token
exchange and refresh may use POST as required by OAuth, but x-brief has no X content-write
backend. Capture's optional public-oEmbed fetch has $0.00 model cost. Secret values never reach
the vault, a log or a prompt, and nothing is resident after the app closes. The ownership model —
what may be changed, by whom, and what deletion means — is in
docs/MEMORY-AND-OWNERSHIP.md; the runtime boundaries are in
docs/AI-RUNTIME.md.
The product's deliberate boundaries and known limits:
- It does not publish to X autonomously. There is no write backend; it opens X's own composer
and you post. See
docs/X-PUBLISHING.md. - It does not treat captured material as your beliefs, and it does not turn model output into your opinions or preferences on its own. A suggestion stays a suggestion; a learned memory stays a proposal until you accept it.
- It does not scrape timelines or automate browsing. One capture is one explicit action on one URL.
- macOS-only today — the capture shortcut, Keychain storage and editor integration are macOS mechanisms.
- Model quality, cost and latency track your configured Hermes route — they depend on the provider and model you configure.
- Some recovery routes need credentials or tools — a vision-capable model, an xAI key, or the
xurlCLI. A refused route is recorded with its remedy, so "could not get more" is never confused with "never tried". - Scheduled collection is dormant. The official X API mode ships intact but unloaded; it needs a paid developer app, and manual capture needs none of it.
| If you want to… | read |
|---|---|
| install x-brief from a fresh clone | docs/SETUP.md |
| learn the everyday loop | docs/WORKFLOW.md |
| see two recorded real workflow runs end to end | docs/EXAMPLE-WORKFLOW.md |
| configure profile, style and tone | docs/PERSONALIZATION.md |
| look up a command, key or CLI verb | docs/COMMANDS.md |
| understand the engineering | docs/ARCHITECTURE.md |
| understand Hermes and Jev | docs/AI-RUNTIME.md |
| see what may change, and what deletion means | docs/MEMORY-AND-OWNERSHIP.md |
| know why manual capture, and what X's rules allow | docs/CAPTURE-COMPLIANCE.md |
| know what x-brief does on X | docs/X-PUBLISHING.md |
| fix something that went wrong | docs/TROUBLESHOOTING.md |
| build on or test the code | docs/DEVELOPMENT.md |
The full catalogue is in docs/README.md.
Standard library only — no Python package dependencies to install: no virtualenv and no
pip install.
x-brief test # the whole suite
PYTHONPATH=. python3 -m unittest discover -s tests -t testsThe suite runs against a throwaway project directory, blocks network access outright, never writes
to ~/Library or your real vault, and replaces Hermes itself at its boundary — so the default run
needs no Hermes installation and no configured provider. See
docs/DEVELOPMENT.md for the test architecture and the reusable
clean-install verification method.
x-brief installs a few optional macOS integrations and keeps all of its runtime state inside the clone. Removing the application does not touch your writing:
x-brief capture uninstall # the capture Service
x-brief schedule uninstall # the scheduled launchd jobs
x-brief auth logout # the stored X OAuth token
rm ~/.local/bin/x-brief ~/.local/bin/xbrief # the global command
rm -rf ~/x-brief # the clone and its stateRun these while the clone still exists — the installed x-brief command runs the clone's
launcher. Your Markdown vault (~/Documents/x-brief-vault) is not touched by any of them — it
is your writing, and deleting it is a separate, deliberate step. The complete procedure, including
the optional Jev Keychain item and how to delete your own data if you really want to, is in
docs/SETUP.md.
MIT — Copyright (c) 2026 Artyom Andreyev.