@namsangboy/aplus-previewer
v0.1.1
Published
Launch, auto-detect, track, and manage local preview dev servers with a CLI and admin dashboard for APlus AI workflows.
Maintainers
Readme
aplus-previewer
aplus-previewer is a TypeScript/ESM package for safely spawning, tracking, and managing local preview dev servers created by agents or user projects.
The package provides:
@namsangboy/aplus-previewer/core: pure lifecycle, policy, marker, ownership, audit, environment, and route helpers.@namsangboy/aplus-previewer/node: file registry store, process lifecycle, project auto-detection, process inventory, orphan sweep, and GC helpers.@namsangboy/aplus-previewer/server: local admin HTTP API.@namsangboy/aplus-previewer/mcp: MCP stdio server and testable MCP tool handler for code agents.@namsangboy/aplus-previewer/admin-ui: React/Vite admin dashboard entrypoint.aplus-previewer: CLI bin for auto/spawn/spawn-group/list/stop/restart/delete/sweep/gc/admin workflows.aplus-previewer-mcp: MCP stdio bin exposing preview lifecycle tools to Hermes, Claude Code, Codex, and other MCP clients.
Install
Global CLI install:
npm install -g @namsangboy/aplus-previewer
aplus-previewer --helpProject-local install:
pnpm add -D @namsangboy/aplus-previewer
pnpm exec aplus-previewer --helpUsage: manage all previews from one dashboard
aplus-previewer stores preview lifecycle state in a registry under --state-dir. The default is the machine-shared $HOME/.aplus-previewer directory (or APLUS_PREVIEWER_STATE_DIR when set), so one dashboard can see previews launched from different project directories by default.
For a deterministic dashboard setup, use the same explicit --state-dir and --workspace-dir on every command:
STATE="$HOME/.aplus-previewer"
WORKSPACE="$HOME/workspace"Auto-detect and launch previews
aplus-previewer auto \
--json \
--state-dir "$STATE" \
--workspace-dir "$WORKSPACE" \
--project demo-project \
--cwd "$WORKSPACE/demo-project"Equivalent shortcut through spawn:
aplus-previewer spawn \
--auto \
--json \
--state-dir "$STATE" \
--workspace-dir "$WORKSPACE" \
--project demo-project \
--cwd "$WORKSPACE/demo-project"Auto-detect scans the workspace for supported preview services, then calls the same safe spawnGroup path. It currently recognizes Node projects (Next.js, Vite, Express), Python projects (FastAPI, Django, Flask), Go, Rails, Spring Boot, and ASP.NET Core.
When a backend and frontend are detected together, the backend starts first and the frontend automatically depends on it. The frontend receives the backend URL via API_BASE_URL plus framework-specific public env keys such as VITE_API_BASE_URL and NEXT_PUBLIC_API_BASE_URL.
Launch a single preview manually
aplus-previewer spawn \
--json \
--state-dir "$STATE" \
--workspace-dir "$WORKSPACE" \
--project demo-project \
--service web \
--cwd "$WORKSPACE/demo-project" \
--command "npm run dev" \
--probe-path /If --port is omitted, aplus-previewer finds an available local port. If the requested port is already owned by an external process, the spawn fails closed and does not kill that process.
Launch a dependent backend/frontend group
Service keys should be identifier-like (backend, frontend, web-api); prototype-sensitive names such as __proto__ are rejected before any service is spawned. probeTimeoutMs is a hard deadline, so smoke configs can fail fast without waiting for the default health-check window.
cat > previewer-group.json <<'JSON'
{
"cwd": "/Users/example/workspace/demo-project",
"host": "127.0.0.1",
"services": [
{
"service": "backend",
"command": ["npm", "run", "dev:api"],
"probePath": "/health",
"probeTimeoutMs": 5000
},
{
"service": "frontend",
"command": ["npm", "run", "dev:web"],
"dependsOn": ["backend"],
"env": {
"API_BASE_URL": "{{services.backend.url}}",
"VITE_API_BASE_URL": "{{services.backend.url}}",
"NEXT_PUBLIC_API_BASE_URL": "{{services.backend.url}}"
},
"probePath": "/",
"probeIntervalMs": 100,
"probeTimeoutMs": 5000
}
]
}
JSON
aplus-previewer spawn-group \
--json \
--state-dir "$STATE" \
--workspace-dir "$WORKSPACE" \
--project demo-project \
--config previewer-group.jsonList, stop, restart, and delete previews
aplus-previewer list \
--json \
--state-dir "$STATE" \
--workspace-dir "$WORKSPACE"To enumerate an intentionally separate project-local registry alongside the primary shared registry, add --source-state-dir (or --all for an aggregate context with the primary source):
aplus-previewer list \
--json \
--state-dir "$STATE" \
--source-state-dir "$WORKSPACE/legacy-project/.aplus-previewer" \
--workspace-dir "$WORKSPACE"Use the preview id returned by list or shown in the dashboard:
aplus-previewer stop <preview-id> \
--json \
--state-dir "$STATE" \
--workspace-dir "$WORKSPACE"
aplus-previewer restart <preview-id> \
--json \
--state-dir "$STATE" \
--workspace-dir "$WORKSPACE"
aplus-previewer delete <preview-id> \
--stop-first \
--json \
--state-dir "$STATE" \
--workspace-dir "$WORKSPACE"delete requires --stop-first for running previews, so registry cleanup cannot silently leave a live process behind.
Start the admin dashboard
aplus-previewer admin \
--state-dir "$STATE" \
--workspace-dir "$WORKSPACE" \
--host 127.0.0.1 \
--port 4180Open:
http://127.0.0.1:4180The dashboard shows previews registered in the same --state-dir plus any explicitly configured aggregate sources and provides:
Previews: ID, project, service, source label/state directory, status, port, URL, PID, and Stop/Restart/Delete actions.Orphans: conservative registry-vs-process inventory checks for stale or suspicious preview processes.Audit: lifecycle, sweep, GC, and policy audit events with source metadata for aggregate rows.
Important: the default registry is machine-shared under
$HOME/.aplus-previewer(orAPLUS_PREVIEWER_STATE_DIR). If you intentionally use separate project-local--state-dirvalues, start the dashboard with--source-state-dirfor each additional registry you want to enumerate.
MCP server for code agents
The package ships aplus-previewer-mcp, a stdio MCP server exposing the same safe lifecycle surface to code agents:
list_previewsspawn_preview/spawn_auto_preview/spawn_preview_group(mutating calls requireintent: "manage-preview")stop_preview/restart_preview/delete_preview(mutating calls requireintent: "manage-preview")read_audit_log
Build before using a local checkout as an MCP server:
pnpm build
node ./dist/mcp/cli.jsHermes Agent config example:
mcp_servers:
aplus_previewer:
command: "node"
args: ["/absolute/path/to/aplus-previewer/dist/mcp/cli.js"]
timeout: 120
connect_timeout: 60Claude Code project-scoped config example:
claude mcp add -s project aplus-previewer -- node /absolute/path/to/aplus-previewer/dist/mcp/cli.jsFor Codex and other code agents, keep AGENTS.md in the target repo and either configure the MCP stdio command when the runtime supports MCP, or call the CLI directly (aplus-previewer auto --json ...) as a fallback.
Programmatic API
Programmatic consumers can call previewer.spawnAuto(...), previewer.spawnGroup(...), or the side-effect-free detectPreviewProject(...) from @namsangboy/aplus-previewer/node; the package export also exposes the @namsangboy/aplus-previewer/mcp MCP entrypoint and the SpawnPreviewAutoInput, SpawnPreviewAutoResult, DetectPreviewProjectInput, DetectedPreviewProject, DetectedPreviewService, DetectedPreviewRole, DetectedPreviewLanguage, DetectedPreviewConfidence, SpawnPreviewGroupInput, and SpawnPreviewGroupResult types.
Development quick start
pnpm install
pnpm test
pnpm typecheck
pnpm buildCLI package smoke:
pnpm test tests/integration/cli.integration.test.ts
pack_dir=$(mktemp -d)
install_dir=$(mktemp -d)
pnpm build
pnpm pack --pack-destination "$pack_dir"
(cd "$install_dir" && npm init -y && npm install --ignore-scripts --no-audit "$pack_dir"/*.tgz)
"$install_dir/node_modules/.bin/aplus-previewer" --helpDocumentation
Read these first for implementation and operations context:
specs/aplus-previewer-package/spec.md— product/architecture/acceptance criteria.specs/aplus-previewer-package/source-spec-roadmap.md— source spec coverage and implementation order.specs/aplus-previewer-package/plan.md— phase plan and verification gates.specs/aplus-previewer-package/tasks.md— execution checklist.docs/api.md— public entrypoints, CLI, and admin API.docs/admin-dashboard.md— dashboard pages, mutation UX, redaction, and validation.docs/safety.md— process ownership, redaction, sweep/GC, and package smoke safety model.docs/aplus-dev-studio-integration.md— recommended migration path for wiring this package back into aplus-dev-studio.docs/code-agent-guide.md— MCP/CLI setup and safe workflows for Hermes, Claude Code, Codex, and other code agents.
Safety principles
- The registry is the single source of truth for preview lifecycle state.
- Destructive actions require ownership revalidation and audit logging.
- Admin bind defaults to
127.0.0.1; public bind requires auth. - GC is disabled and dry-run by default.
- Sweep scan is read-only; sweep execute requires explicit selection and confirmation.
- The CLI admin server wires process-inventory revalidation and signaling. Programmatic
createAdminServercallers must provide their own sweep kill/revalidation callbacks; otherwise sweep execute fails closed. - Unknown, foreign, spoofed, or unresolved processes are never auto-killed.
- Registry, audit, CLI JSON, and dashboard surfaces must not expose raw env values or credentials.
