pages:
   stage: build
   script:
-  - pip install sphinx sphinx_rtd_theme slixmpp
+  - pip install sphinx sphinx_rtd_theme slixmpp feedparser python-debianbts
   - sphinx-build -d ./build/doctrees doc/source -b html ./public -D html_theme=sphinx_rtd_theme
   artifacts:
     paths:
 
     :undoc-members:
     :show-inheritance:
 
-.. user autodecorator:: with sphinx v2.0
-.. autofunction:: sid.sid.botcmd(hidden, name)
+.. need sphinx v2.0 for autodecorator
+.. autodecorator:: sid.sid.botcmd(hidden, name)
 
 Plugin base
 -----------
 
    :caption: Contents:
 
    doc.rst
+   plugins.rst
    contribute.rst
 
 Indices and tables
 
--- /dev/null
+Available plugins
+=================
+
+Generic plugins
+---------------
+
+.. automodule:: sid.echo
+    :members:
+    :show-inheritance:
+
+.. autoclass:: sid.feeds.Feeds
+    :members:
+    :show-inheritance:
+
+Debian plugins
+--------------
+
+.. automodule:: sid.archive
+    :members:
+    :show-inheritance:
+
+.. automodule:: sid.bts
+    :members:
+    :show-inheritance:
+
+
+.. vim: spell spelllang=en
 
 
 
 class Archive(Plugin):
-    """Fetch package info from the archive
+    """Fetches package info from the archive
     """
+    #: Current stable Suite
     stable_codename = 'buster'
+    #: Pakage name regexp
     re_pkg = re_compile(r'(?P<package>[0-9a-z.+-]+)$')
 
     def __init__(self, bot):
 
     @botcmd
     def archive(self, rcv, args):
-        """Fetch pkg versions info from the archive:
-
-        !archive pkg-name : Returns package versions (by suite)
         """
+        **command** ``!archive pkg-name`` : Returns package versions
+        (by suite)"""
         if not args:
             return
         if len(args) > 1:
 
 
 class Bugs(Plugin):
     """Gets bugs info from the BTS
+
+    .. note::
+      This plugin depends on external module: **python-debianbts**
     """
     re_bugs = re_compile(r'(?<=#)(\d{6,7})')
     re_pkg = re_compile(r'(?P<package>[0-9a-z.+-]+)$')
                               self.bot.room, self.muc_message)
 
     def muc_message(self, msg):
-        """Handler method dealing with MUC incoming messages"""
+        """Handler method dealing with MUC incoming messages.
+
+        Intercepts bugs number in MUC messages (as #629234), replies a bug
+        summary."""
         # Does not reply to myself
         if msg['mucnick'] == self.bot.nick:
             return
 
     @botcmd
     def bugs(self, rcv, args):
-        """Intercepts bugs number in messages (as #629234), reply a bug summary.
-        !bugs pkg-name : Returns latest bug reports if any
+        """
+        **command** ``!bugs pkg-name`` : Returns latest bug reports if any
         """
         if not args:
             return
 
 
 
 class Echo(Plugin):
-    """Drop a message to be sent when someone gets online.
+    """Drops a message to be sent when someone gets online.
     """
 
     def __init__(self, bot):
                               self.bot.room, self.log_presence)
 
     def log_presence(self, pres):
-        """Register presence"""
+        """Handler method registering MUC participants presence"""
         self.log.debug('%s: %s', pres['muc']['nick'], pres['type'])
         nick = pres['muc']['nick']
         self.presence.update({nick: (pres['muc']['role'], pres['type'])})
 
     @botcmd
     def tell(self, message, args):
-        """drop a message to be sent when someone gets online.
-        !tell queue        : messages in queue
-        !tell <nick> <msg> : append <msg> to <nick> in queue"""
+        """
+        **commands**:
+
+        * ``!tell queue``        : messages in queue
+        * ``!tell <nick> <msg>`` : append <msg> to <nick> in queue"""
         if not len(args):
             msg = 'Missing arguments:\n{}'.format(self.tell.__doc__)
             self.reply(message, msg)
 
 # -*- coding: utf-8 -*-
 
-# Copyright (C) 2011, 2014 kaliko <kaliko@azylum.org>
+# Copyright (C) 2011, 2014, 2020 kaliko <kaliko@azylum.org>
 
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 
 
 class Feeds(Plugin):
+    """
+    .. note::
+      Feeds plugin depends on external module: **feedparser**
+    """
+
+    #: Time between feeds check
     TEMPO = 60
+    #: Default feeds to monitor
     FEEDS = [
         'https://www.debian.org/security/dsa',
         'https://www.debian.org/News/news',
     @botcmd
     def feeds(self, rcv, args):
         """feeds monitors debian project related feeds.
-        !feeds : registred feeds list
-        !feeds last : last check time"""
+
+        **commands**:
+
+        * ``!feeds`` : registred feeds list
+        * ``!feeds last`` : last check time"""
         if 'last' in args:
             self.reply(rcv, 'Last feeds check: %s' % self.th_mon.last_check)
             return