JA

jlapenna/agent-lcars

Developer tools
1 stars Quality 64 Trend 25Apache-2.0

LCARS operations console and agent telemetry pipeline

Overview

Agent LCARS is the control plane for headless Claude Code, Codex, and OpenCode work on the shared self-hosted GitHub Actions runner fleet. It turns GitHub issues into accountable agent work, shows maintainers where attention is needed, and retains the session evidence behind each outcome. To dispatch work, add exactly one routing label to an issue in an onboarded repository: The shared agent protocol is the complete behavioral contract for every dispatched run. The LCARS skill is a situational control-plane reference for developers changing dispatch and reconciliation machinery. The console then tracks the run from intake through review, merge, and any maintainer follow-up. See Operations for Work API access and parked-item cleanup. Use the console for decisions and inspection; use the supporting services when working on a specific part of the fleet. The console keeps the active fleet, its decision queue, and its session history in focused workspaces.

README

Agent LCARS

Agent LCARS is the control plane for headless Claude Code, Codex, and OpenCode work on the shared self-hosted GitHub Actions runner fleet. It turns GitHub issues into accountable agent work, shows maintainers where attention is needed, and retains the session evidence behind each outcome.

Dispatch

To dispatch work, add exactly one routing label to an issue in an onboarded repository:

Label Agent
agent:claude Claude Code
agent:codex Codex
agent:opencode OpenCode

The shared agent protocol is the complete behavioral contract for every dispatched run. The LCARS skill is a situational control-plane reference for developers changing dispatch and reconciliation machinery. The console then tracks the run from intake through review, merge, and any maintainer follow-up.

Operating surfaces

See Operations for Work API access and parked-item cleanup.

Use the console for decisions and inspection; use the supporting services when working on a specific part of the fleet.

Surface Use
Console queue (/) Work requiring a maintainer action
Console agents (/agents) Active runs, CLI sessions, and recent outcomes
Console sessions (/sessions) Search and inspect session records
apps/telemetry-watcher Interactive and CI session telemetry
apps/runner-autoscaler Runner placement and lifecycle
apps/github-actions-exporter GitHub Actions metrics
infra/terraform GCP services, IAM, storage, secrets, and budget

Console views

The console keeps the active fleet, its decision queue, and its session history in focused workspaces. The Decision Inbox is the starting point for work that needs a human response; Agents is the live operational view; and the Session Archive is the durable record for investigation and audit.

Active agents

Session archive

Documentation map

The full task-oriented index is docs/README.md, and ARCHITECTURE.md maps system ownership and proof boundaries. Common entry points:

Need Source of truth
Onboard a repository to the agent fleet Repository onboarding
Agent labels and routing GitHub label contract
Credentials and GitHub App identity Fleet credentials and bot identities
CI dispatch and published actions Published actions
Local/CI E2E boundary E2E security boundary
E2E test policy E2E reliability
Runtime diagnosis Lifecycle systems

Development

For setup, FQDN sharing, fixture reset, browser journeys, and troubleshooting, use the local console SUT playbook.

Use the Node and pnpm versions pinned in package.json:

pnpm install
pnpm verify

For iterative console/control-plane work, use the credential-free development stack instead of rebuilding the standalone production bundle. The commands are Nx targets (with uncached runtime operations and no production-build prerequisite), following Sprinkles’ serve-emulator / serve-lan target convention:

pnpm dev
# Equivalent: ./tools/nx run @agent-lcars/console:serve-emulator

This starts the Next.js development server with hot reload, the Firebase Auth and Firestore emulators, the Firebase emulator UI, local-only authentication, and populated synthetic fixtures. It listens only on loopback: the console is at http://127.0.0.1:4300 and the emulator UI is at http://127.0.0.1:4301. No production credential is loaded or required.

For feedback from another machine, use the host’s fully qualified DNS name:

FQDN=dev.example.net pnpm dev:lan
# Equivalent: FQDN=dev.example.net ./tools/nx run @agent-lcars/console:serve-lan

The console is then at http://dev.example.net:4300. Its FQDN must resolve to a private IPv4 interface on the serving host; only that interface and loopback are bound. Next.js receives the same FQDN for hot-reload origins. Emulators remain private on loopback because LCARS accesses them server-side. Host/origin checks reject DNS rebinding and cross-origin requests before injecting the synthetic administrator. This is a trusted-LAN fixture preview, not a public authenticated service. No secrets or dotenv files are changed.

Use pnpm dev:reset to restore the synthetic data without restarting the server and pnpm dev:status for a quick health check. These commands and pnpm dev:test discover the running stack’s FQDN automatically; there is no need to repeat FQDN. A second worktree can use an independent seven-port range:

pnpm dev -- --port-base 4310
pnpm dev:reset -- --port-base 4310

Run pnpm dev:test against the running stack for the existing native Work edit/save/reload journey. Select another existing browser journey using Playwright’s usual arguments, without rebuilding or restarting:

pnpm dev:test -- native-work.spec.ts --grep 'reply persists'
pnpm dev:test -- --port-base 4310 native-work.spec.ts --grep 'opens populated'
FQDN=dev.example.net pnpm dev:test

Browser tests reset the stack’s synthetic data, then restore the populated fixture set afterward. Failure traces and screenshots are saved to the temporary diagnostics directory printed by the command. Auth-cookie and production-cache tests still use the hermetic standalone E2E entrypoint; the development stack injects the fixture administrator for ordinary browser requests, while preserving explicit E2E identity headers from tests.

Stop the foreground stack with Ctrl-C. The supervisor shuts down the Next.js server and its Firebase emulator processes together.

The real Orchestrator runs in-process with the Work API and writes durable task/run/outbox/queue state to the Firestore emulator. External GitHub calls use local fixtures. This stack does not launch QueueExecutor, direct runners, provider processes, the telemetry watcher, or periodic reconcile/schedule ticks; queued work will not execute by itself. It is a control-plane integration SUT, not a complete fleet execution SUT.

Start with the focused document that matches your task. This README intentionally does not duplicate deployment steps, runner topology, credential setup, or migration history; those operational contracts live with their owning systems and should be verified there.

Console startup configuration

The console validates static backend configuration before accepting requests. Local development uses the same boot checks as production. Supply the runtime variables declared in apps/console/apphosting.yaml, including the GitHub App client ID and PEM private key, webhook secret, project and webhook queue/location, AUTH_URL, QUICK_TASK_EVIDENCE_BUCKET, and AGENT_LCARS_WORK_AUDIENCE. Store credentials in the supported private environment; never commit them. A blank value or malformed App key fails startup with the variable name, without printing the credential. Dispatch drains continue rebuilding token providers so key rotation is still observed.

Hermetic E2E uses tools/e2e/ci.env plus an unregistered App key generated in memory for each Playwright server launch. The standalone bundle smoke generates its own ephemeral key. Neither path imports deployment credentials or bypasses the production boot validator. An autoscaler using a custom Work audience must set LCARS_WORK_AUDIENCE to match the console’s explicit audience.

View this README on GitHub

Recommended Tools

Try a different keyword or remove a filter.

Install

npx skillfish add jlapenna/agent-lcars