Skip to content

Feature/aio process manager - #399

Merged
awehttam merged 12 commits into
claudesbbsfrom
feature/aio-process-manager
Jul 11, 2026
Merged

Feature/aio process manager#399
awehttam merged 12 commits into
claudesbbsfrom
feature/aio-process-manager

Conversation

@awehttam

Copy link
Copy Markdown
Owner

No description provided.

awehttam and others added 12 commits June 29, 2026 17:13
Introduces a Go-based AIO process manager as the primary recommended
deployment method for BinktermPHP, replacing manual systemd/cron setup.

- binktermphp-pm: supervises all BinktermPHP daemons with restart
  policies, exponential back-off, health monitoring (TCP/HTTP probes
  for Postgres and Caddy), and a live ANSI console dashboard
- binktermphp-ctl: companion CLI for start/stop/restart/logs/reload
  and the new set-enabled command via Unix domain socket IPC
- Console dashboard: [s]tart, [S]top, [r]estart, [e]nable/disable
  with status bar feedback; auto-attaches if PM is already running
- Daemon mode (--daemon): re-execs self as detached background process
- Cross-platform: build-tagged platform files isolate Unix-only
  signals (SIGHUP, SIGUSR1, SIGWINCH, Setsid) from Windows
- config/aio.json.example: default service manifest with always-on
  core daemons and opt-in optional services
- makego.cmd / makego.sh: build both binaries to the project root
- Bumps version to 1.9.10

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
FrankenPHP replaces the standalone Caddy + PHP runtime with a single
supervised process managed by binktermphp-pm.

- config/Caddyfile.example: ready-to-use FrankenPHP config covering
  php_server (SimpleRouter routing), /ws reverse-proxy to BinkStream
  (realtime_daemon on :6010), gzip/zstd compression, security headers,
  automatic HTTPS via built-in ACME, and commented-out worker mode
- config/aio.json.example: add disabled "frankenphp" service entry
  (frankenphp run --config config/Caddyfile); enable it and remove the
  caddy health check to switch from standalone Caddy to FrankenPHP

Background PHP daemons continue to use the system php binary.
PostgreSQL and BinkStream remain separate supervised services.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a new BBS admin page at /admin/services that lets sysops enable or
disable services defined in config/aio.json without editing the file
directly. Always-on services are shown as locked. Writes are handled
through the admin daemon (get_aio_config / save_aio_config commands) so
the web process never touches config files directly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Health checks:
- Add postgres_env check type: opens a real authenticated connection using
  DB_* vars from the root .env file (lib/pq) rather than just probing the
  TCP port
- Add site_verify check type: reads SITE_URL from .env and GETs
  SITE_URL/api/verify, expecting a 2xx response
- .env is parsed once at startup and cached
- Update config/aio.json.example to use the new check types

Shutdown:
- StopAll now accepts a progress callback; in foreground mode the shutdown
  screen prints one [ok]/[killed] line per service as it stops, then
  "Shutdown complete." — previously the screen just cleared and hung silently

Attach / detach:
- q in attach mode now detaches without stopping the daemon (was
  incorrectly sending stop_all to the daemon)
- Q in attach/local mode sends stop_all and shuts the daemon down
- Header adapts: "[q]detach  [Q]stop daemon" when attached, "[q]uit" locally
- Add IsAttached() and StopDaemon() to the Controller interface

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
makego.cmd / makego.sh now build four targets into dist/<os>-<arch>/:
  windows-amd64, linux-amd64, darwin-amd64, darwin-arm64

binktermphp-pm.cmd / binktermphp-pm.sh and binktermphp-ctl.cmd /
binktermphp-ctl.sh are single entry-point wrappers in the project root
that dispatch to the correct dist/ binary for the current platform.
The shell scripts auto-detect OS and arch at runtime and error clearly
if the binary hasn't been built yet.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Admin Services page now shows live runtime status (state, PID, uptime,
  restarts) and exposes start/stop/restart/logs actions per service
- admin_daemon proxies pm commands via forwardToPm(); reads ipc_secret
  from aio.json and performs auth handshake before each request
- pm IPC server validates shared secret on every connection when
  ipc_secret is configured; auth failures are logged and rejected
- Added TCP IPC listener (ipc_addr) so PHP on Windows can reach pm
  without Unix socket support; secret protects the TCP port
- binktermphp-ctl and pm --attach mode both pick up ipc_addr/ipc_secret
  from aio.json automatically via resolveClient()
- Added linux/arm64 build target to makego.cmd and makego.sh
- Fixed badge readability on dark/amber/greenterm/cyberpunk themes:
  neutral badges (disabled state, restart policy, health type) now use
  bg-secondary which all themes explicitly style, instead of bg-light
  with a hard-coded text colour

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
tools/binktermphp-pm/ and the root-level makego.cmd/makego.sh build
scripts have been moved to the standalone repository at
github.com/awehttam/binktermphp-pm.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…s match

The unread/received netmail filters only matched messages where to_name
equaled the user's username or real_name, but BinkdProcessor::findTargetUser()
can resolve the recipient's user_id via fidonet_address even when to_name is
a nickname that doesn't match either. Those messages appeared under "All"
(matched via user_id) but were silently excluded from "Unread", making the
unread count and tab undercount real unread netmail. Now match by user_id
OR the legacy name+address check, consistently across getNetmail(),
getThreadedNetmail(), the netmail stats API, and the dashboard badge query.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
….json, update AIO docs

The earlier netmail unread-count fix used n.user_id as an unconditional
recipient match, but user_id is the SENDER (not the recipient) for
locally-delivered netmail (same-system user-to-user, or a message to the
sysop), and that row's is_sent stays FALSE forever since nothing gets
spooled. That meant a user's own locally-sent netmail could incorrectly
count as unread in their own account. The user_id match is now excluded
whenever the querying user is identifiable as the sender of that row
(from_name matches them AND from_address is one of the system's own
addresses), so only genuine inbound mail from remote systems benefits
from the recipient-by-address fallback.

Also:
- Admin -> BBS Settings -> Services now only appears when config/aio.json
  exists, since it only applies to installs experimenting with the
  external binktermphp-pm process manager.
- docs/UPGRADING_1.9.10.md and docs/proposals/BinktermPHP-AIO.md updated
  to reflect that binktermphp-pm/binktermphp-ctl now live in their own
  repository (github.com/awehttam/binktermphp-pm) and that this release's
  support for it is experimental, with no migration path yet, plus the
  netmail unread-count fix and its sender-exclusion refinement.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@awehttam
awehttam merged commit 550f4db into claudesbbs Jul 11, 2026
3 checks passed
@awehttam
awehttam deleted the feature/aio-process-manager branch July 12, 2026 00:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant