@@ -392,6 +392,85 @@ hooks config
392392
393393---
394394
395+ # # 🖥️ 16. CLI Utility: `hooks serve`
396+
397+ The project provides a `hooks serve` command-line utility for running the webhook server directly, similar to `rails server`.
398+
399+ # ## Usage
400+
401+ ` ` ` bash
402+ hooks serve [options]
403+ ` ` `
404+
405+ # ### Common Options
406+
407+ * `-p`, `--port PORT` — Port to listen on (default: 3000)
408+ * `-b`, `--bind HOST` — Bind address (default: 0.0.0.0)
409+ * `-e`, `--env ENV` — Environment (default: production)
410+ * `-c`, `--config PATH` — Path to endpoints config directory
411+ * `-s`, `--settings PATH` — Path to global settings file
412+ * `--no-puma` — (Advanced) Use the default Rack handler instead of Puma
413+ * `-h`, `--help` — Show help message
414+
415+ # ## Example
416+
417+ ` ` ` bash
418+ hooks serve -p 8080 -c ./config/endpoints -s ./config/settings.yaml
419+ ` ` `
420+
421+ # ## How it Works
422+
423+ * The CLI loads configuration and settings from CLI args, ENV, or defaults.
424+ * It builds the Rack app using `Hooks.build(...)`.
425+ * By default, it starts the server using Puma (via `Rack::Handler::Puma`).
426+ * If Puma is not available, it falls back to the default Rack handler (e.g., WEBrick), but Puma is strongly recommended and included as a dependency.
427+
428+ # ## Implementation Sketch
429+
430+ ` ` ` ruby
431+ # bin/hooks (excerpt)
432+ require "hooks-ruby"
433+ require "optparse"
434+
435+ options = {
436+ port: ENV.fetch("PORT", 3000),
437+ bind: ENV.fetch("BIND", "0.0.0.0"),
438+ env: ENV.fetch("RACK_ENV", "production"),
439+ config: ENV["HOOKS_CONFIG_DIR"] || "./config/endpoints",
440+ settings: ENV["HOOKS_SETTINGS"] || "./config/settings.yaml",
441+ use_puma: true
442+ }
443+
444+ OptionParser.new do |opts|
445+ opts.banner = "Usage: hooks serve [options]"
446+ opts.on("-pPORT", "--port=PORT", Integer, "Port to listen on") { |v| options[:port] = v }
447+ opts.on("-bHOST", "--bind=HOST", String, "Bind address") { |v| options[:bind] = v }
448+ opts.on("-eENV", "--env=ENV", String, "Environment") { |v| options[:env] = v }
449+ opts.on("-cPATH", "--config=PATH", String, "Endpoints config directory") { |v| options[:config] = v }
450+ opts.on("-sPATH", "--settings=PATH", String, "Settings file") { |v| options[:settings] = v }
451+ opts.on("--no-puma", "Use default Rack handler instead of Puma") { options[:use_puma] = false }
452+ opts.on("-h", "--help", "Show help") { puts opts; exit }
453+ end.parse!(ARGV)
454+
455+ app = Hooks.build(config: options[:config], settings: options[:settings])
456+
457+ if options[:use_puma]
458+ require "rack/handler/puma"
459+ Rack::Handler::Puma.run(app, Host: options[:bind], Port: options[:port], environment: options[:env])
460+ else
461+ Rack::Handler.default.run(app, Host: options[:bind], Port: options[:port])
462+ end
463+ ` ` `
464+
465+ # ## Notes
466+
467+ * Puma is included as a runtime dependency and is the default server for all environments.
468+ * The CLI is suitable for both development and production use.
469+ * All configuration options can be set via CLI flags, ENV variables, or config files.
470+ * The CLI prints a startup banner with the version, port, and loaded endpoints.
471+
472+ ---
473+
395474# # 📦 13. Hello-World Default
396475
397476When no configuration is provided, the framework serves a demo endpoint for verification :
0 commit comments