docs: def serve(context: Context, port=8000, browsersync_port=3000, browsersync_ui_port=3030):
      """
      Starts a development server with auto-building and live-reload
      """
      try:
          from watchdog.observers import Observer
      except ImportError:
          context.pip_command('install', 'watchdog>0.8,<0.9')
          from watchdog.observers import Observer
  
      from watchdog.events import PatternMatchingEventHandler
  
      class RebuildHandler(PatternMatchingEventHandler):
          def __init__(self, *args, **kwargs):
              super().__init__(*args, **kwargs)
              self._patterns = ['*.js', '*.scss', '*.html']
              self._ignore_directories = True
              self.builder = None
              self.rebuild_javascript = threading.Event()
              self.rebuild_stylesheets = threading.Event()
  
          def on_any_event(self, event):
              if self.builder:
                  self.builder.cancel()
              extension = event.src_path.rsplit('.', 1)[-1].lower()
              if extension == 'js':
                  self.rebuild_javascript.set()
              elif extension == 'scss':
                  self.rebuild_stylesheets.set()
              self.builder = threading.Timer(3, self.rebuild)
              self.builder.start()
  
          def rebuild(self):
              if self.rebuild_javascript.is_set():
                  self.rebuild_javascript.clear()
                  context.debug('Triggering javascript build')
                  bundle_javascript(context)
              if self.rebuild_stylesheets.is_set():
                  self.rebuild_stylesheets.clear()
                  context.debug('Triggering stylesheet build')
                  bundle_stylesheets(context)
              context.debug('Reloading browsers')
              context.node_tool('browser-sync', 'reload', '--port=%s' % browsersync_port)
  
      context.info('Watching sources')
      observer = Observer()
      paths = [
          context.app.common_asset_source_path,
          context.app.asset_source_path,
          context.app.common_templates_path,
          context.app.templates_path,
      ]
      handler = RebuildHandler()
      for path in paths:
          observer.schedule(handler, path, recursive=True)
      observer.setDaemon(True)
      observer.start()
  
      context.info('Starting browser sync')
      browsersync_args = ['start', '--host=localhost', '--no-open',
                          '--logLevel', {0: 'silent', 1: 'info', 2: 'debug'}[context.verbosity],
                          '--port=%s' % browsersync_port, '--proxy=localhost:%s' % port,
                          '--ui-port=%s' % browsersync_ui_port]
      browsersync = functools.partial(context.node_tool, 'browser-sync', *browsersync_args)
      threading.Thread(target=browsersync, daemon=True).start()
  
      context.info('Starting web server')
      return start(context, port=port)