# Project pack: wallabag @ 72bdffa

Facts about **wallabag** for an AI following the [BespokeAI handover guide](https://handoff.bespokeai.software/guide/v1.md). This pack is pinned to one version and never changes after publication.

> wallabag is a read-it-later service you run yourself. Save any web page with one click from your browser or phone, and wallabag keeps a clean copy of the text and pictures with no adverts or pop-ups. Read it later on any device, even offline in the apps, add highlights and notes, and tag articles automatically. You can bring your saved articles from Pocket, Instapaper and others.

## Version and source
- Repository: https://github.com/wallabag/wallabag
- Pinned commit: `72bdffa41fd6b73a547e140206cf702e7bd29f8f`. Use exactly this version.
- Get it: `git clone https://github.com/wallabag/wallabag wallabag && cd wallabag && git checkout 72bdffa41fd6b73a547e140206cf702e7bd29f8f`
- Or download a zip: https://github.com/wallabag/wallabag/archive/72bdffa41fd6b73a547e140206cf702e7bd29f8f.zip
- Official docs: https://doc.wallabag.org
- Licence: **MIT**. Very permissive. You can use, change and share it, even commercially. If you pass on copies, keep the copyright notice and licence text.

## Running it
- Easiest:

  ```sh
  docker run -d --name wallabag -p 8080:80 -v wallabag-data:/var/www/wallabag/data -v wallabag-images:/var/www/wallabag/web/assets/images -e APP_SECRET=$(openssl rand -hex 16) -e WALLABAG_BASE_URL=http://localhost:8080 -e DATABASE_URL=sqlite:////var/www/wallabag/data/db/wallabag.sqlite wallabag/wallabag
  # open http://localhost:8080 and log in as wallabag / wallabag, then change the password.
  # This follows the install docs at the pinned commit; older image releases may use different variable names (see Docker Hub).
  ```

- Needs: Docker, or PHP 8.2+ with Composer, a web server and SQLite, PostgreSQL or MySQL, For development, GNU make, Node.js and Yarn (or the Docker dev stack)
- Develop: `cp docker/php/env.example docker/php/env && make dev-docker-up && make dev-setup   # http://127.0.0.1:8000; run make dev-watch for assets`
- Test: `make test`
- Check/lint: `make lint`
- Build: `make build`
- Stack: php, javascript, twig, scss (Symfony 5.4, Doctrine, Twig, Webpack Encore, Stimulus, Materialize CSS, Graby). Difficulty for a non-developer with an AI: **moderate**. A long-lived Symfony app with good structure: controllers in src/Controller/, pages in templates/ (Twig), styles in assets/scss/ and small Stimulus controllers in assets/controllers/. Tagging rules, custom CSS and the API cover a lot without code. Code changes need PHP 8.2+ and Node for the assets; the Docker dev stack makes that easier.

## The project's own AI instructions
Read these in the repository before changing code: `.github/CONTRIBUTING.md`.

## Customisation points (settings → extend → code)
- **user-settings** [settings]: Items per page, your reading speed (for "x min" estimates), where to go after archiving, thumbnails and language. Light, dark or automatic theme is in the side menu. → `Config → Settings (doc/content/user/configuration/settings.md)`
- **article-display** [settings]: Make the reading page comfortable for you without any code. → `Config → Article display (font family, font size, line height, maximal width)`
- **tagging-rules** [settings]: Tag articles automatically, e.g. "readingTime <= 3" → "quick read", or anything from bbc.co.uk → "news". → `Config → Tagging rules (doc/content/user/configuration/tagging_rules.md)`
- **feeds** [settings]: Private Atom feeds of unread, starred or tagged articles for a feed reader or e-reader. → `Config → Feeds (doc/content/user/configuration/rss.md)`
- **instance-settings** [settings]: Sharing buttons, public links for articles, paywall logins, sign-ups and the instance name. → `Internal settings (admin) and environment variables in .env (doc/content/admin/internal_settings.md, parameters.md)`
- **custom-css** [extend]: Instance-wide styles loaded on every page, such as a reading font or larger text. No rebuild. → `web/custom.css (doc/content/admin/custom_css.md)`
- **api-and-apps** [extend]: Save from scripts, shortcuts or other apps, and read on Android or iOS. → `REST API with OAuth clients (src/Controller/Api/, doc/content/developer/api/); browser extension and phone apps`
- **importers** [extend]: Bring in years of saved articles from another service. → `Import page (src/Import/, src/Controller/Import/) for Pocket, Instapaper, Pinboard, Omnivore, browser bookmarks…`
- **templates-and-styles** [code]: Change how lists and the reading page look and behave. → `templates/ (e.g. templates/Entry/entry.html.twig for the reading view), assets/scss/, assets/controllers/`
- **backend** [code]: New features or data, such as a reading streak or a 'read aloud' button. → `src/Controller/, src/Entity/ + Doctrine migrations in migrations/, text in translations/messages.en.yml`

## Must keep working
- Saved articles, tags and highlights. Back up the database and images before upgrades or code changes.
- The REST API and OAuth, which the browser extension and phone apps rely on.
- Each user only sees their own articles; public share links only for articles the user chose to share.
- Database changes need a Doctrine migration in migrations/.

## Staying updatable
Tagging rules, feeds, internal settings, custom.css and the API cover most personal tweaks without a fork. Upstream accepts pull requests against master that pass `make test` and the linters (see .github/CONTRIBUTING.md). The project name is always written in lower case: wallabag.

## Data, costs and safety
- Personal data: **yes**. Stored in: Database (SQLite file in data/db/ by default, or PostgreSQL/MySQL) for articles, tags and highlights; saved pictures in web/assets/images. What you read says a lot about you. Back up the database and the images folder (see doc/content/admin/backup.md). You can also export everything as JSON, CSV or ePUB from the app.
- Service: Email (any provider via MAILER_DSN) (optional, free with most providers): Account confirmation, password resets and two-factor codes by email.
- Service: Redis or RabbitMQ (optional, free (self-hosted)): Run big imports (thousands of articles) in the background.
- Service: The websites you save (required, free): wallabag downloads each saved page from its website. Paywalled sites can use your own login (site credentials).
- Setting `APP_SECRET` (**secret**: the person enters it themselves, never in chat): Random secret for sessions and security tokens. The example value in .env must be replaced.
- Setting `WALLABAG_BASE_URL`: The full address you open wallabag at, e.g. https://read.example.com.
- Setting `DATABASE_URL` (**secret**: the person enters it themselves, never in chat): Database address. SQLite by default; can contain a password for PostgreSQL or MySQL.
- Setting `WALLABAG_REGISTRATION_ENABLED`: 1 lets anyone create an account; keep 0 for a private instance.
- Setting `WALLABAG_SERVER_NAME`: The name of your instance shown to users.
- Setting `DEFAULT_LOCALE`: Default interface language, e.g. en or fr.
- Setting `MAILER_DSN` (**secret**: the person enters it themselves, never in chat): Email server address for confirmations and resets. Often includes a password.
- Setting `WALLABAG_FROM_EMAIL`: The sender address on wallabag's emails.
- Setting `REDIS_URL`: Redis address for background imports.
- Change the default wallabag / wallabag login and set a random APP_SECRET straight away.
- Keep WALLABAG_REGISTRATION_ENABLED=0 on an internet-facing server, and use HTTPS.
- Shared article links are public to anyone who has them.
- Site credentials for paywalled sites are stored on your server. Only add them if you trust where it runs.

---

# Customising wallabag

wallabag is a well-organised Symfony app. **Most personal tweaks are settings, tagging rules or a little custom CSS.** Use levels 1 and 2 first.

## Level 1: Settings (no code)
- **Your settings:** Config → Settings.
  - Items per page and reading speed (wallabag recalculates "x min" for every article).
  - What happens after you archive or delete, thumbnails and interface language.
- **Reading page:** Config → *Article display*. Font family, font size, line height and maximal width.
- **Theme:** light, dark or automatic, from the side menu.
- **Automatic tags:** Config → *Tagging rules*.
  - Examples: `readingTime <= 3` → `quick read`; `domainName = "bbc.co.uk"` → `news`.
  - See `doc/content/user/configuration/tagging_rules.md`.
- **Ignore origin rules:** Config → *Ignore origin rules*, so redirect links (newsletters, link shorteners) are saved under the real site.
- **Feeds:** Config → *Feeds*. Create a token for private Atom feeds of unread, starred, archived or tagged articles.
- **Instance (admin):**
  - *Internal settings* control sharing buttons, public article links, paywall logins and analytics (`doc/content/admin/internal_settings.md`).
  - Environment variables in `.env` control sign-ups, the instance name, email and the database (`doc/content/admin/parameters.md`).

## Level 2: Extend (no fork)
- **Custom CSS:** create `web/custom.css`. It is loaded on every page for all users (`doc/content/admin/custom_css.md`).
- **Apps:** browser extension (wallabagger), Android and iOS apps. Create an API client under *API clients management* (`doc/content/apps/`).
- **REST API** with OAuth (`doc/content/developer/api/`). Save, tag, archive or export from scripts and shortcuts.
- **Imports:** Pocket, Instapaper, Pinboard, Omnivore, Readability, Shaarli, Delicious, browser bookmarks and other wallabag servers. Use Redis or RabbitMQ for very big imports (`doc/content/admin/asynchronous.md`).
- **Exports:** ePUB, PDF, JSON, CSV and XML for one article or a whole list.

## Level 3: Code
Read upstream `.github/CONTRIBUTING.md` first.

| Change | Where |
|---|---|
| Reading page | `templates/Entry/entry.html.twig`, styles in `assets/scss/_article.scss` |
| Article lists and cards | `templates/Entry/entries.html.twig`, `templates/Entry/_card_*.html.twig`, `assets/scss/_cards.scss` |
| Dark theme | `assets/scss/_dark_theme.scss` |
| Browser behaviour | `assets/controllers/` (Stimulus) |
| Pages and actions | `src/Controller/` (e.g. `EntryController.php`, `ConfigController.php`) |
| API | `src/Controller/Api/` |
| New data | `src/Entity/` + a Doctrine migration in `migrations/` |
| New importer | `src/Import/` + `src/Controller/Import/` |
| Text | `translations/messages.en.yml` (other languages via Weblate) |

## Running locally
- **Just use it:**
  1. Run `docker run -p 8080:80 -e APP_SECRET=… -e WALLABAG_BASE_URL=http://localhost:8080 -e DATABASE_URL=sqlite:////var/www/wallabag/data/db/wallabag.sqlite -v wallabag-data:/var/www/wallabag/data -v wallabag-images:/var/www/wallabag/web/assets/images wallabag/wallabag`
  2. Log in as wallabag / wallabag and change the password.
  3. Check Docker Hub for the variable names your image version expects.
- **Develop (Docker):**
  1. `cp docker/php/env.example docker/php/env`
  2. `make dev-docker-up`, then `make dev-setup`
  3. Open http://127.0.0.1:8000.
  4. Run `make dev-watch` in another terminal for CSS and JavaScript.
- **Develop (own PHP 8.2+):** `make dev`, then `make run` later.
- **Check:** `make test` (unit, integration, functional) and `make lint` (PHP-CS-Fixer, PHPStan, TwigCS, ESLint, Stylelint, translations).

## Pitfalls
- Back up the database and `web/assets/images` before upgrades or code changes.
- Front-end changes need a rebuild (`make build` or `make dev-watch`). Editing files in `web/build/` directly gets overwritten.
- Phone apps and the browser extension use the API. Don't change existing API responses.
- Some sites block or change their pages. Fetching problems are usually site-config issues (`doc/content/user/errors_during_fetching.md`), not wallabag bugs.

---
Machine-readable: [bespoke.yaml](https://handoff.bespokeai.software/p/wallabag/72bdffa/bespoke.yaml) · Agent skill: [SKILL.md](https://handoff.bespokeai.software/p/wallabag/72bdffa/SKILL.md)
