Initial build: stash server + browser extension
Server (Express + better-sqlite3 + FTS5, mirroring keep's stack):
/api/capture (upsert-on-url, per PROPOSAL.md's dedup decision),
/api/articles (list/search/mark-read/delete), plus a minimal
server-rendered reading list and reader view at / and /read/:id
(token passed as ?t= there since browser navigation can't set an
Authorization header). Bearer-token auth generated via `npm run
token` — no login flow, matching keep's one-time identity
registration pattern.
Extension (Manifest V3, sideloaded, no store distribution): toolbar
click or context menu "Send to stash" runs @mozilla/readability
(vendored into extension/lib/) against the current page, falling back
to raw rendered HTML when extraction comes back too thin. Options
page for one-time server URL + token entry.
Verified end-to-end with the real extension loaded in a live Chromium
instance (not just unit-tested extraction logic): capture against a
real page, dedup-on-recapture, mark-read, FTS5 search, 401 on missing
auth, and both server-rendered views all confirmed working.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-12 23:23:01 +02:00
|
|
|
{
|
|
|
|
|
"name": "stash",
|
|
|
|
|
"version": "0.1.0",
|
|
|
|
|
"license": "MIT",
|
|
|
|
|
"type": "module",
|
|
|
|
|
"scripts": {
|
|
|
|
|
"dev:server": "tsx watch --env-file=.env src/server/index.ts",
|
|
|
|
|
"token": "tsx src/server/gen-token.ts",
|
2026-07-13 19:00:36 +02:00
|
|
|
"tokens": "tsx src/server/list-tokens.ts",
|
|
|
|
|
"revoke-token": "tsx src/server/revoke-token.ts",
|
Initial build: stash server + browser extension
Server (Express + better-sqlite3 + FTS5, mirroring keep's stack):
/api/capture (upsert-on-url, per PROPOSAL.md's dedup decision),
/api/articles (list/search/mark-read/delete), plus a minimal
server-rendered reading list and reader view at / and /read/:id
(token passed as ?t= there since browser navigation can't set an
Authorization header). Bearer-token auth generated via `npm run
token` — no login flow, matching keep's one-time identity
registration pattern.
Extension (Manifest V3, sideloaded, no store distribution): toolbar
click or context menu "Send to stash" runs @mozilla/readability
(vendored into extension/lib/) against the current page, falling back
to raw rendered HTML when extraction comes back too thin. Options
page for one-time server URL + token entry.
Verified end-to-end with the real extension loaded in a live Chromium
instance (not just unit-tested extraction logic): capture against a
real page, dedup-on-recapture, mark-read, FTS5 search, 401 on missing
auth, and both server-rendered views all confirmed working.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-12 23:23:01 +02:00
|
|
|
"build": "tsc",
|
|
|
|
|
"start": "node --env-file=.env dist/server/index.js"
|
|
|
|
|
},
|
|
|
|
|
"dependencies": {
|
|
|
|
|
"express": "^4.19.2",
|
|
|
|
|
"better-sqlite3": "^11.3.0",
|
|
|
|
|
"cors": "^2.8.5"
|
|
|
|
|
},
|
|
|
|
|
"devDependencies": {
|
|
|
|
|
"@types/express": "^4.17.21",
|
|
|
|
|
"@types/node": "^22.0.0",
|
|
|
|
|
"@types/better-sqlite3": "^7.6.11",
|
|
|
|
|
"@types/cors": "^2.8.17",
|
|
|
|
|
"tsx": "^4.15.0",
|
|
|
|
|
"typescript": "^5.5.0"
|
|
|
|
|
}
|
|
|
|
|
}
|