feat(service): add Hermes-style singleton user service with lifecycle CLI - #5
Open
Martins6 wants to merge 1 commit into
Open
feat(service): add Hermes-style singleton user service with lifecycle CLI#5Martins6 wants to merge 1 commit into
Martins6 wants to merge 1 commit into
Conversation
… CLI Promote Acolyte from a foreground-only bot to a per-user singleton background service. Add public lifecycle commands, OpenCode session wrappers, last-N log tail, strict workspace validation, persisted workspace path, atomic runtime state, and service-aware self-update. - cmd/start becomes the service controller (install/enable/start). - cmd/stop [--forever], cmd/restart, cmd/status round out the lifecycle. - Hidden acolyte __daemon is the worker invoked by systemd/launchd. - internal/service Manager interface selects systemd (Linux) or launchd (macOS) at runtime via injected Runner for tests. - internal/runtime tracks PID + readiness in ~/.acolyte/.service/state.json with atomic writes and kill(0) liveness checks. - internal/daemon wires existing bot/notifier/scheduler/startup-check with proper context cancellation and Stop hooks. - internal/opencode/session shells out to `opencode session list` and `opencode export <id>` inside the workspace with a LookPath guard. - internal/logger/tail replaces the old date positional logs command with `acolyte logs [N] [--date today|YYYY-MM-DD]` honoring multi-line entries and skipping non-daily log files. - workspace.StrictValidate lists missing template paths and suggests `acolyte new <path>` instead of silently repairing. - internal/config gains LoadIfExists and WriteWorkspacePath; viper no longer auto-creates the singleton config during read paths. - cmd/update now restarts through the service manager instead of re-execing inside the same process. Also adds an OpenCode-powered PR reviewer workflow adapted from the Forge review setup: .github/workflows/opencode.yml triggers on PR events and `/oc` or `/opencode` comments, and a custom pr-reviewer agent encodes Acolyte-specific review conventions. Verification: go vet ./..., go test ./..., gofmt -l ., and GOOS=linux/darwin cross-builds all succeed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Promote Acolyte from a foreground-only bot to a per-user singleton
background service. Add public lifecycle commands, OpenCode session
wrappers, last-N log tail, strict workspace validation, persisted
workspace path, atomic runtime state, and service-aware self-update.
Command surface
acolyte start [--workspace PATH]— install, enable and start the per-user service.acolyte stop [--forever]— stop the service;--foreverdisables autostart.acolyte restart— restart the running service.acolyte status— running/stopped + workspace + autostart (exit 3 when stopped).acolyte session list/acolyte session <id>—opencode session list/opencode export <id>inside the active workspace.acolyte logs [N] [--date today|YYYY-MM-DD]— tail the last N application log entries (default 10).Architecture
acolyte __daemonis the worker invoked by systemd (Linux) or launchd (macOS).internal/serviceexposes aManagerinterface with platform implementations selected viaruntime.GOOS; service-rendered files (systemd units, plists) usetext/template, neverfmt.Sprintf.internal/runtimewrites~/.acolyte/.service/state.jsonatomically with PID liveness checks (kill(pid, 0)).internal/daemonwires existing bot/notifier/scheduler with proper context cancellation andStop()hooks.workspace.StrictValidatelists every missing template path and suggestsacolyte new <path>instead of silently repairing.cmd/updatenow restarts via the service manager instead of re-execing inside the same process.PR reviewer workflow
Also adds an OpenCode-powered PR reviewer adapted from the Forge review setup:
.github/workflows/opencode.yml— triggers onpull_request(non-draft),issue_comment, andpull_request_review_comment; runs when the body contains/ocor/opencode..opencode/agent/pr-reviewer.md— Acolyte-aware checklist (Go module layout, Conventional Commits,gofmt/go vet/go test, cross-platform service support, noos.ExitinRunE, context-propagatedexec.Command, atomic runtime-state writes)..opencode/command/review.md— local/reviewslash command..opencode/opencode.json— model and default agent.Verification
go vet ./...— cleango test ./...— all packages passgofmt -l .— cleanGOOS=linux go build ./...andGOOS=darwin go build ./...— both succeedDocs
docs/features/feat-background-service.md(new)docs/features/feat-pr-reviewer.md(new)docs/features/OVERVIEW.mdandLOG-FEATS.mdupdatedREADME.mdCLI table + new "Running as a background service" sectionBreaking changes
acolyte logs DATEis replaced byacolyte logs --date DATE(default behavior is "last 10 entries").acolyte startnow refuses to start if the configured workspace is incomplete; runacolyte new <path>first.