| description | FreshRSS introduction and conventions for AI agents and human contributors |
|---|
FreshRSS is an open-source news aggregator supporting RSS/ATOM/WebSub and also Web scraping.
The market segment is mostly self-hosting, although multiple user accounts are supported. It is supposed to be installed on a modest server (mostly, but not limited to, Linux) and can be accessed through a Web UI and an API.
It is written in PHP to make it easy to deploy and easy to contribute to.
More information can be found in README and in the documentation published at https://freshrss.github.io/FreshRSS/en/
.github/instructions/contain the instructions that primarily match filename patterns..github/skills/contain the skills to achieve higher-level goals, potentially combining multiple instructions.AGENTS.mdis the entry point description for AI coding agents and contributors, referencing other documents such as instructions and skills.- Favour standard conventions over vendor-specific ones.
- To reduce duplication, refer to enforceable configuration files instead of excessive free-text repetitions.
app/Controllers/– Controllers extendFreshRSS_ActionController, named as{name}Controller.phpwith classFreshRSS_{name}_Controllerapp/Models/– Domain models extendMinz_Model.- DAOs may have some database-specific inheritance, e.g.:
*DAO.php(base or MySQL),*DAOSQLite.php(SQLite),*DAOPGSQL.php(PostgreSQL)
- DAOs may have some database-specific inheritance, e.g.:
app/views/{controller}/– View templates are.phtmlfiles mixing PHP and HTMLapp/views/helpers/– Reusable view elements with$this->partial('name')lib/core-extensions/orextensions/– FreshRSS extensionslib/Minz/– Core framework: routing, sessions, translations, extensions, PDO abstractionlib/lib_rss.php– Containspl_autoload_registerand other global functionsp/– Public Web root. Only the content of this folder should be exposed if possible (p/should not be visible in the public URL)- Only the
p/i/path should be access controlled. The main entry point isp/i/index.php p/api/greader.php– Primary API for mobile clientsp/api/pshb.php– Receive realtime pushes via WebSubp/themes/– UI themes
- Only the
- Constants:
constants.phpoverridden inconstants.local.php - System config:
config.default.phpoverridden indata/config.php - User config:
config-user.default.phpoverridden indata/users/{username}/config.php
ℹ Access via
FreshRSS_Context::systemConf()andFreshRSS_Context::userConf()
Three database backends supported: SQLite, PostgreSQL, MySQL/MariaDB. The SQL differences are implemented through inheritance:
// Base DAO with common queries
class FreshRSS_EntryDAO extends Minz_ModelPdo { }
// Database-specific overrides
class FreshRSS_EntryDAOSQLite extends FreshRSS_EntryDAO { }
class FreshRSS_EntryDAOPGSQL extends FreshRSS_EntryDAO { }A factory pattern selects the correct DAO, e.g.:
FreshRSS_Factory::createEntryDao();Important: in database, VARCHAR/TEXT fields are HTML-encoded, except attributes fields, which contain JSON, and which sub-strings are not HTML-encoded.
ℹ Recommended before committing
# Runs all tests: PHPUnit, PHPCS, PHPStan, typos
make test-all
# Auto-fix all trivial issues: whitespace, RTL CSS, translations
make fix-all
# See a list of commands:
make helpCI/CD is defined in .github/workflows/tests.yml
A Dev Container is available under .devcontainer/.
ℹ Check Docker documentation.
There are scripts in cli/ for admin tasks, such as:
./cli/list-users.phpℹ Check CLI documentation.
When possible, it is best to run as Web server user:
sudo -u www-data cli/actualize-user.php --user aliceor at least re-apply the file permissions after CLI operations:
cli/access-permissions.sh