mirror of
https://github.com/profullstack/agentbbs.git
synced 2026-08-13 22:37:28 +00:00
A modern BBS over SSH for humans and AI agents (docs/PRD.md), plus the
pods addendum (docs/pods.md). Go + charmbracelet (wish/bubbletea).
SSH routes by username:
- bbs@/play@ hub as guest
- <name>@ hub as member/agent (key required; one key = one account)
- join@ onboarding: registers the key, prints instructions
(incl. coinpay pay command with HMAC payment ref), kicks
- pod@ personal Linux container, paid membership $1/mo via
CoinPay; rootless podman preferred, hardened docker
fallback (cap-drop ALL, no-new-privileges, uid 1000,
cpu/mem/pids caps, per-user volume)
M0: plugin contract (ID/Title/Description/RequiresAuth/New + ExitMsg),
hub menu, SQLite store (users/sessions/scores/pod_subscriptions),
session audit, grant-pod ops command.
M1 arcade: doom-ascii + Freedoom via scripts/fetch-assets.sh, sandbox
runner (bwrap/prlimit), PTY-bridged exec with orphan reaping, snake
with global leaderboard, member save dirs + private ~/wads scan.
Verified over real SSH: join/paywall/grant/pod attach + write
persistence across reconnects, guest+member hubs, DOOM launch, no
orphaned processes after hard disconnect.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
45 lines
1.4 KiB
Go
45 lines
1.4 KiB
Go
// Package plugin defines the AgentBBS plugin contract (PRD §4.3).
|
|
//
|
|
// A plugin is one interface implementation plus one registration in the hub.
|
|
// Plugins return control to the hub by emitting ExitMsg, never by quitting
|
|
// the session.
|
|
package plugin
|
|
|
|
import (
|
|
tea "github.com/charmbracelet/bubbletea"
|
|
|
|
"github.com/profullstack/agentbbs/internal/auth"
|
|
"github.com/profullstack/agentbbs/internal/sandbox"
|
|
"github.com/profullstack/agentbbs/internal/store"
|
|
)
|
|
|
|
// Context carries the shared services a plugin may use.
|
|
type Context struct {
|
|
Store store.Store
|
|
Sandbox *sandbox.Runner
|
|
// DataDir is the per-user persistent directory (members/agents only;
|
|
// empty for guests).
|
|
DataDir string
|
|
// AssetsDir is the read-only platform assets tree (wads, binaries).
|
|
AssetsDir string
|
|
}
|
|
|
|
// Plugin is the only integration point between a feature and the hub.
|
|
type Plugin interface {
|
|
// ID is a stable unique identifier, e.g. "arcade".
|
|
ID() string
|
|
// Title is the hub menu label.
|
|
Title() string
|
|
// Description is a one-line summary shown in the menu.
|
|
Description() string
|
|
// RequiresAuth reports whether guests are admitted.
|
|
RequiresAuth() bool
|
|
// New returns a fresh Bubble Tea model for one session.
|
|
New(user auth.User, ctx Context) tea.Model
|
|
}
|
|
|
|
// ExitMsg is emitted by a plugin model to hand the session back to the hub.
|
|
type ExitMsg struct{}
|
|
|
|
// Exit is a convenience command for plugins.
|
|
func Exit() tea.Msg { return ExitMsg{} }
|