no ecosystem files in git; officer-setup generates one
Deleted all four — ecosystem.config.cjs, .light., .mac.light. and the .profile. they derived from. The repository now contains no ecosystem file at all, and .gitignore keeps it that way. officer-setup writes one at the end, describing exactly the six processes a core install runs: officer, officer-anthropic-proxy, officer-agent, officer-opencode, officer-pty and officer-headscale. No profiles, no derivation, no plugins. The four existed because a profile has to subtract from something, so the full list had to name every plugin's process whether or not anybody installed it — and a test then had to assert the two files still agreed. Generating one file removes the subtraction, the second list and the test that policed them. It is .cjs, not the .js PM2's docs use, and that is not a preference: package.json declares "type": "module", so a .js file here is ESM and `module.exports` throws. PM2 require()s the config. Sections 10 (Services) and 11 (Verify) are built on top of it — write, startOrRestart, save, optional boot hook, then check every process is online with a sane restart count AND that the API actually answers on PORT. A process can be `online` and serving nothing, so the port is asked directly rather than inferred. That completes all eleven sections. catalogue.test.ts required both deleted files at import, so it could not even load. Its central assertion — "the store offers exactly what light leaves out" — has no meaning without a full list to subtract from, which is the point of the change. Replaced by two weaker but real checks: the store must not offer a core process, and every process it names must have a sidecar directory to run. The second catches the same typo the old one did without needing a manifest of everything; verified it holds for all 15 catalogue entries. app-store/pm2.ts starts a sidecar with `--only` against this file, which now holds core alone — so it can stop a plugin but cannot start one that was never written in. Marked `[open]` there rather than left to be discovered: appending a plugin's entry is the plugin system's job. Generated one in a scratch directory and required it with node: six apps, correct cwd on each, valid CommonJS. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -52,6 +52,8 @@ source "$SCRIPT_DIR/officer-setup/lib/env.sh"
|
||||
source "$SCRIPT_DIR/officer-setup/lib/secrets.sh"
|
||||
# shellcheck source=officer-setup/lib/build.sh
|
||||
source "$SCRIPT_DIR/officer-setup/lib/build.sh"
|
||||
# shellcheck source=officer-setup/lib/services.sh
|
||||
source "$SCRIPT_DIR/officer-setup/lib/services.sh"
|
||||
|
||||
trap 'echo ""; echo -e "${RED}╔══════════════════════════════════════════════════╗${NC}"; echo -e "${RED}║ OFFICER SETUP FAILED${NC}"; echo -e "${RED}║ Step: ${CURRENT_STEP:-unknown}${NC}"; echo -e "${RED}║ Line: $LINENO${NC}"; echo -e "${RED}║ Command: $BASH_COMMAND${NC}"; echo -e "${RED}╚══════════════════════════════════════════════════╝${NC}"' ERR
|
||||
|
||||
@@ -632,10 +634,105 @@ if ! skip; then
|
||||
fi
|
||||
|
||||
# =============================================================================
|
||||
# NOT BUILT YET
|
||||
# 10. Services
|
||||
# =============================================================================
|
||||
# 10 Services pm2 startOrRestart · save · startup
|
||||
# 11 Verify are the processes actually up
|
||||
|
||||
step "Services"
|
||||
if ! skip; then
|
||||
echo ""
|
||||
info "pm2 — $(ecosystem_file)"
|
||||
echo " The ecosystem file is GENERATED, not checked in. It describes this"
|
||||
echo " install and nothing else, so nothing in git can drift from it."
|
||||
echo ""
|
||||
echo " six processes:"
|
||||
for entry in "${CORE_PROCESSES[@]}"; do
|
||||
IFS='|' read -r _name _script _args <<<"$entry"
|
||||
printf " %-24s %s %s\n" "$_name" "$_script" "$_args"
|
||||
done
|
||||
echo ""
|
||||
echo " Nothing else. Every plugin adds its own entry when it is installed."
|
||||
echo ""
|
||||
|
||||
if confirm "Write it and start them?"; then
|
||||
write_ecosystem
|
||||
ok "written — $(ecosystem_file)"
|
||||
|
||||
if OUT="$(pm2_start)"; then
|
||||
ok "processes started"
|
||||
pm2_save >/dev/null 2>&1 && ok "process list saved (survives a pm2 restart)"
|
||||
|
||||
echo ""
|
||||
if confirm "Start them on boot too?"; then
|
||||
if pm2_enable_startup; then
|
||||
ok "pm2 will resurrect them at boot"
|
||||
SUMMARY+=("Services: 6 processes started, enabled at boot")
|
||||
else
|
||||
warn "could not enable the boot hook — run 'pm2 startup' yourself and follow it"
|
||||
SUMMARY+=("Services: 6 processes started; boot hook NOT enabled")
|
||||
fi
|
||||
else
|
||||
SUMMARY+=("Services: 6 processes started; not enabled at boot")
|
||||
fi
|
||||
else
|
||||
warn "pm2 did not start cleanly"
|
||||
echo "$OUT" | tail -12 | sed 's/^/ /'
|
||||
SUMMARY+=("Services: FAILED to start — see the output above")
|
||||
fi
|
||||
else
|
||||
warn "skipped by request"
|
||||
SUMMARY+=("Services: SKIPPED by request")
|
||||
fi
|
||||
step_ok
|
||||
fi
|
||||
|
||||
# =============================================================================
|
||||
# 11. Verify
|
||||
# =============================================================================
|
||||
|
||||
step "Verify"
|
||||
if ! skip; then
|
||||
echo ""
|
||||
info "Are the processes actually up?"
|
||||
echo ""
|
||||
|
||||
VERIFY_BAD=0
|
||||
while IFS='|' read -r vname vstatus vrestarts; do
|
||||
[[ -z "$vname" ]] && continue
|
||||
if [[ "$vstatus" == "online" ]]; then
|
||||
if (( vrestarts > 3 )); then
|
||||
warn "$(printf '%-24s online, but restarted %s times — check: pm2 logs %s' "$vname" "$vrestarts" "$vname")"
|
||||
VERIFY_BAD=$((VERIFY_BAD + 1))
|
||||
else
|
||||
ok "$(printf '%-24s online' "$vname")"
|
||||
fi
|
||||
else
|
||||
warn "$(printf '%-24s %s — check: pm2 logs %s' "$vname" "$vstatus" "$vname")"
|
||||
VERIFY_BAD=$((VERIFY_BAD + 1))
|
||||
fi
|
||||
done < <(pm2_status_lines)
|
||||
|
||||
echo ""
|
||||
# A process can be `online` and still be failing to serve — a restart loop takes
|
||||
# a few seconds to show up in the counter, and the app can be up with a broken
|
||||
# database. So the port is asked directly.
|
||||
if curl -fsS --max-time 5 "http://127.0.0.1:${ENV_PORT:-9000}/api" >/dev/null 2>&1; then
|
||||
ok "the API answers on 127.0.0.1:${ENV_PORT:-9000}"
|
||||
SUMMARY+=("Verify: API answering on port ${ENV_PORT:-9000}")
|
||||
else
|
||||
warn "nothing answered on 127.0.0.1:${ENV_PORT:-9000}/api"
|
||||
echo " pm2 logs officer is where the reason will be."
|
||||
VERIFY_BAD=$((VERIFY_BAD + 1))
|
||||
SUMMARY+=("Verify: the API did NOT answer on port ${ENV_PORT:-9000}")
|
||||
fi
|
||||
|
||||
if (( VERIFY_BAD == 0 )); then
|
||||
echo ""
|
||||
ok "Officer is running. Open ${ENV_PUBLIC_URL:-http://localhost:${ENV_PORT:-9000}} and the"
|
||||
echo " first-run screen will create the owner account."
|
||||
fi
|
||||
step_ok
|
||||
fi
|
||||
|
||||
|
||||
echo ""
|
||||
echo -e "${BOLD} Pre-flight complete.${NC} The remaining sections are not built yet."
|
||||
|
||||
Reference in New Issue
Block a user