LessWrong/EAF Power Reader and User Archive (userscript)
(Beta announcement to get some testing/feedback before I post this to main. Please report bugs/UX friction/perf issues and feature requests, here if you want others to see and discuss, or on Github if minor.)
I present a browser userscript to help keep up with LW/EAF content (it’s a way to view all recent comments/posts, with a lot of helpful features), and to save, read, and search a user’s entire LW/EAF output.
Quick Start: Install Tampermonkey first (links for Chrome, Firefox, Edge, Safari), then click here to install Power Reader. After install, go to (or refresh) any LW/EAF page and use the injected Power Reader link in the site header, or the User Archive link on user profile pages.
Features
Power Reader mode
Loads and threads up to 800 comments (most recent or set “load from” date) in one view, merged with posts in the same time frame.
All comments are grouped by post, and posts are sorted by “tree karma”, i.e., the post with highest karma unread comment is shown first.
Color indicators: point-based gradients, recency highlighting, reply-to-you highlighting, read-state styling.
Marks and remembers which posts/comments you’ve read (based on scrolling).
Author preference controls (↑ / ↓) to indicate favorite and disfavored authors, which feeds into visual highlighting.
Parent/reply navigation and loading ([^], [t], [r]). E.g., use [t] to jump to the top of a thread, then [r] to load all of its children.
Post controls ([e], [a], [c], [n]) to view posts and associated comments without leaving the page.
Send post/comment to free AI chatbots with thread context and customizable prompt prefix (optionally include all descendants with Shift):
g / Shift+G: send to Google AI Studio
m / Shift+M: send to Arena.ai Max
Replicates LW/EAF voting/reactions features.
Syncs key reader states (e.g., author preferences and read marks) across devices/sessions when logged in (using an external DB to avoid loading LW/EAF servers).
User Archive mode
Offline cache (in browser storage) with incremental sync.
Multiple archive views: card, index, thread-full, and thread-placeholder.
Structured search:
plain terms
“quoted phrases”
regex (/pattern/flags)
operators such as author:, replyto:, type:, score:, date:, scope:
scope:all mode includes authored + context comments.
Similar controls as in Power Reader Mode, to easily see context, replies, and send to AI.
I posted the original version of this script years ago, but it eventually broke due to site architecture changes. Around the same period, I also wrote a server-side script that put all comments/posts for a user on one page for easier saving and searching.
This rebuild is in part a vibe/agentic coding experiment, and many new features were added relative to the original. Most docs, code, and tests were generated with AI assistance, with me steering features, doing manual testing, and correcting mistakes.
To LW devs/admins
To support cross-device syncing, the script currently generates and stores a secret key in abTestOverrides, in a way that shouldn’t affect site functionality (it only adds a namespaced string key, pr_sync_secret_v1, while preserving existing abTestOverrides entries and not changing any experiment/feature flags), but please let me know if you’d prefer a different implementation, e.g., storing the secret elsewhere or adding an LW-side field for script state.
I present a browser userscript to help keep up with LW/EAF content (it’s a way to view all recent comments/posts, with a lot of helpful features), and to save, read, and search a user’s entire LW/EAF output.
This can be considered out of “beta” status. Not sure I’ll get around to making a top-level post about it, so I’m just dropping a note here that it’s ready for people to use. I’ve been using it daily as my main way of reading LW and EAF for several weeks.
I recommend against the use of Math.random() in general, unless you are highly performance constrained. I’ve checked, and it appears browsers have commonly supported a better random source since 2015[1]/early 2016 at the latest. The code below should be entirely correct to replace both the primary and fallback UUIDv4 generation code, once adapted to a function in a TS module.
// Function available since 2015.
const uuid_b = new Uint8Array(16);
self.crypto.getRandomValues(uuid_b);
let uuid_hex = "";
for (let i = 1; i <= 16; i++) {
let octet = uuid_b[i-1];
if (i == 9) {
// Set the correct "variant" (type).
octet = octet & 0xBF | 0x80
}
let o_hex = octet.toString(16);
// Branch on data.
if (o_hex.length == 1) {
// Big endian, least significant bits are
// on the right, therefore small numbers
// that only result in a single byte out
// need to be padded on the *left*.
o_hex = `0${o_hex}`
}
if (i == 7) {
// Set the correct version.
o_hex = "4" + o_hex[1]
}
uuid_hex = `${uuid_hex}${o_hex}`
if (i%2 == 0 && i > 3 && i < 11) {
uuid_hex = `${uuid_hex}-`
}
}
console.log(uuid_hex)
If that still won’t work, I could help you do slightly better by manually implementing SHA3-256 in JavaScript, since we’re not really worried about timing attacks at this level.
To support cross-device syncing, the script currently generates and stores a secret key in abTestOverrides, in a way that shouldn’t affect site functionality
Huh, I never thought of using that field that way but I guess it is the one and only non-public user-editable untyped field on the user object schema, so that makes sense. We aren’t likely to delete this field or data within it in the near term, and will try to remember to shoot an email if it looks like there’s some reason why we’re going to. That said it is kind of a hack, and it does make that field security-sensitive if it wasn’t before, so there is nonzero risk.
A note for the future: We’re experimenting with LW integrations with AI agents—mostly oriented around AIs making API calls directly, rather than using agents to build software tools that invoke the APIs—and as a result some new stuff has been added, and more will be added in the near future. Documentation for the AI-agent-oriented features are at /api/SKILL.md and updates to that documentation will appear there. We have a markdown-ified version of the frontend (good for an AI that wants to read markdown but not stable for structured parsing), and some (pre-beta buggy) APIs for letting an AI agent edit posts that you give them access to.
LessWrong/EAF Power Reader and User Archive (userscript)
(Beta announcement to get some testing/feedback before I post this to main. Please report bugs/UX friction/perf issues and feature requests, here if you want others to see and discuss, or on Github if minor.)
I present a browser userscript to help keep up with LW/EAF content (it’s a way to view all recent comments/posts, with a lot of helpful features), and to save, read, and search a user’s entire LW/EAF output.
Quick Start: Install Tampermonkey first (links for Chrome, Firefox, Edge, Safari), then click here to install Power Reader. After install, go to (or refresh) any LW/EAF page and use the injected Power Reader link in the site header, or the User Archive link on user profile pages.
Features
Power Reader mode
Loads and threads up to 800 comments (most recent or set “load from” date) in one view, merged with posts in the same time frame.
All comments are grouped by post, and posts are sorted by “tree karma”, i.e., the post with highest karma unread comment is shown first.
Color indicators: point-based gradients, recency highlighting, reply-to-you highlighting, read-state styling.
Marks and remembers which posts/comments you’ve read (based on scrolling).
Author preference controls (
↑/↓) to indicate favorite and disfavored authors, which feeds into visual highlighting.Parent/reply navigation and loading (
[^],[t],[r]). E.g., use [t] to jump to the top of a thread, then [r] to load all of its children.Post controls (
[e],[a],[c],[n]) to view posts and associated comments without leaving the page.Send post/comment to free AI chatbots with thread context and customizable prompt prefix (optionally include all descendants with
Shift):g/Shift+G: send to Google AI Studiom/Shift+M: send to Arena.ai MaxReplicates LW/EAF voting/reactions features.
Syncs key reader states (e.g., author preferences and read marks) across devices/sessions when logged in (using an external DB to avoid loading LW/EAF servers).
User Archive mode
Offline cache (in browser storage) with incremental sync.
Multiple archive views: card, index,
thread-full, andthread-placeholder.Structured search:
plain terms
“quoted phrases”
regex (
/pattern/flags)operators such as
author:,replyto:,type:,score:,date:,scope:scope:allmode includes authored + context comments.Similar controls as in Power Reader Mode, to easily see context, replies, and send to AI.
The script is open source on GitHub.
Notes
I posted the original version of this script years ago, but it eventually broke due to site architecture changes. Around the same period, I also wrote a server-side script that put all comments/posts for a user on one page for easier saving and searching.
This rebuild is in part a vibe/agentic coding experiment, and many new features were added relative to the original. Most docs, code, and tests were generated with AI assistance, with me steering features, doing manual testing, and correcting mistakes.
To LW devs/admins
To support cross-device syncing, the script currently generates and stores a secret key in abTestOverrides, in a way that shouldn’t affect site functionality (it only adds a namespaced string key, pr_sync_secret_v1, while preserving existing abTestOverrides entries and not changing any experiment/feature flags), but please let me know if you’d prefer a different implementation, e.g., storing the secret elsewhere or adding an LW-side field for script state.
This can be considered out of “beta” status. Not sure I’ll get around to making a top-level post about it, so I’m just dropping a note here that it’s ready for people to use. I’ve been using it daily as my main way of reading LW and EAF for several weeks.
I recommend against the use of
Math.random()in general, unless you are highly performance constrained. I’ve checked, and it appears browsers have commonly supported a better random source since 2015[1]/early 2016 at the latest. The code below should be entirely correct to replace both the primary and fallback UUIDv4 generation code, once adapted to a function in a TS module.If that still won’t work, I could help you do slightly better by manually implementing SHA3-256 in JavaScript, since we’re not really worried about timing attacks at this level.
https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues#browser_compatibility
Thank you, I’ve taken your suggestion and removed all uses of Math.random().
Huh, I never thought of using that field that way but I guess it is the one and only non-public user-editable untyped field on the user object schema, so that makes sense. We aren’t likely to delete this field or data within it in the near term, and will try to remember to shoot an email if it looks like there’s some reason why we’re going to. That said it is kind of a hack, and it does make that field security-sensitive if it wasn’t before, so there is nonzero risk.
A note for the future: We’re experimenting with LW integrations with AI agents—mostly oriented around AIs making API calls directly, rather than using agents to build software tools that invoke the APIs—and as a result some new stuff has been added, and more will be added in the near future. Documentation for the AI-agent-oriented features are at
/api/SKILL.mdand updates to that documentation will appear there. We have a markdown-ified version of the frontend (good for an AI that wants to read markdown but not stable for structured parsing), and some (pre-beta buggy) APIs for letting an AI agent edit posts that you give them access to.