54 lines
1.9 KiB
Markdown
54 lines
1.9 KiB
Markdown
|
|
# stash
|
||
|
|
|
||
|
|
A self-hosted read-later tool. Click "Send to stash" in the browser, the
|
||
|
|
current page's article content is extracted and stored on your own
|
||
|
|
server — full-text searchable, with a plain reader view. No third party
|
||
|
|
ever sees your reading list.
|
||
|
|
|
||
|
|
Two pieces, neither useful alone:
|
||
|
|
|
||
|
|
- **Server** (`src/server`) — Express + SQLite (via `better-sqlite3`),
|
||
|
|
FTS5 full-text search, a minimal server-rendered reading list + reader
|
||
|
|
view, and the `/api/*` endpoints the extension talks to.
|
||
|
|
- **Extension** (`extension/`) — Manifest V3, sideloaded (not published to
|
||
|
|
any store). Runs [`@mozilla/readability`](https://github.com/mozilla/readability)
|
||
|
|
against the current page to strip nav/ads/chrome and keep just the
|
||
|
|
article, falling back to the raw rendered page if extraction comes back
|
||
|
|
too thin to be useful.
|
||
|
|
|
||
|
|
Full design and the reasoning behind the scope boundaries: [PROPOSAL.md](./PROPOSAL.md).
|
||
|
|
|
||
|
|
## Server setup
|
||
|
|
|
||
|
|
```bash
|
||
|
|
cp .env.example .env
|
||
|
|
npm install
|
||
|
|
npm run token -- my-laptop # prints a bearer token — paste it into the extension's options
|
||
|
|
npm run dev:server
|
||
|
|
```
|
||
|
|
|
||
|
|
## Extension setup
|
||
|
|
|
||
|
|
1. `chrome://extensions` → enable Developer mode → "Load unpacked" → select `extension/`
|
||
|
|
2. Click the extension icon once, or use "Options" from its context menu, to open the options page
|
||
|
|
3. Enter your server's URL and the token from `npm run token`
|
||
|
|
|
||
|
|
Then either click the toolbar icon or right-click a page → "Send to stash".
|
||
|
|
|
||
|
|
## Reading
|
||
|
|
|
||
|
|
Visit `http://your-server:3070/?t=<token>` — a plain list of what's been
|
||
|
|
captured, with search and an unread filter. Click through to `/read/:id`
|
||
|
|
for the cleaned reader view.
|
||
|
|
|
||
|
|
## Status
|
||
|
|
|
||
|
|
Built and verified end-to-end: capture → server storage → full-text
|
||
|
|
search → mark-read → reader view, driven through the actual extension
|
||
|
|
(loaded in a real Chromium instance, not just unit-tested logic) against
|
||
|
|
a live server. Not yet deployed anywhere.
|
||
|
|
|
||
|
|
## License
|
||
|
|
|
||
|
|
MIT.
|