Skip to content

ncolesummers/loopworks

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

105 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Loopworks

Loopworks is an agentic software factory portal for planning, executing, validating, and improving software delivery loops. GitHub Issues are the source of truth for roadmap, planning, milestones, decisions, and execution state. Vercel is the application visibility surface for previews, deployments, and build status.

Stack

  • Next.js App Router, TypeScript, Bun
  • ShadCN/UI and Tailwind CSS
  • Auth.js GitHub SSO
  • Postgres and Drizzle
  • Biome, Vitest, Playwright, Storybook
  • Markdownlint for Markdown documentation
  • Pino structured logging
  • Eve, Vercel Workflows, Vercel Sandbox, Vercel AI Gateway integration points

Local Development

bun install
bun run dev

For local UI work without GitHub OAuth credentials:

bun run dev:fixture

To inspect a signed GitHub issue webhook fixture without sending it:

bun run github:webhook-fixture -- --kind agent-ready
bun run github:webhook-fixture -- --kind spike-agent-ready

The fixture defaults to http://127.0.0.1:3000/api/github/webhooks, uses GITHUB_WEBHOOK_SECRET, and only posts to the local webhook route when --send is provided. Sending is restricted to loopback URLs.

Environment

Copy .env.example to .env.local for local development. The fixture server only needs the defaults from .env.example; real GitHub SSO, webhooks, database persistence, and Vercel deployment visibility use these variables:

  • AUTH_SECRET
  • AUTH_GITHUB_ID
  • AUTH_GITHUB_SECRET
  • LOOPWORKS_AUTH_BYPASS
  • LOOPWORKS_ALLOWED_GITHUB_USERS
  • LOOPWORKS_ALLOWED_GITHUB_ORGS
  • LOOPWORKS_AGENT_READY_LOOP_ENABLED
  • LOOPWORKS_DEVELOPMENT_LOOP_ENABLED
  • LOOPWORKS_RESEARCH_LOOP_ENABLED
  • LOOPWORKS_PORTAL_DATA_MODE
  • LOOPWORKS_EVE_TEST_RECEIPT_SECRET
  • LOOPWORKS_EVE_TEST_WRITER_FIXTURE_MODE
  • LOG_LEVEL
  • DATABASE_URL
  • OTEL_EXPORTER_OTLP_PROTOCOL
  • OTEL_EXPORTER_OTLP_ENDPOINT
  • OTEL_EXPORTER_OTLP_TRACES_HEADERS
  • OTEL_EXPORTER_OTLP_METRICS_HEADERS
  • OTEL_SERVICE_NAME
  • OTEL_RESOURCE_ATTRIBUTES
  • GITHUB_APP_ID
  • GITHUB_APP_PRIVATE_KEY
  • GITHUB_WEBHOOK_SECRET
  • VERCEL_ACCESS_TOKEN
  • VERCEL_TEAM_ID
  • VERCEL_TEAM_SLUG

OpenTelemetry is registered through @vercel/otel. Local development is safe by default: leave the OTLP exporter variables blank unless you intentionally want to ship telemetry. For the ADR 0012 Axiom preview proof, use OTLP/HTTP protobuf, send traces to an Axiom Events dataset with OTEL_EXPORTER_OTLP_TRACES_HEADERS, and send metrics to a dedicated Axiom Metrics dataset with OTEL_EXPORTER_OTLP_METRICS_HEADERS. Pino stdout logs stay attached to Vercel runtime logs with the active traceId; direct Pino-to-Axiom log shipping is tracked separately by issue #65.

Validation

bun run format:check
bun run lint
bun run agent-docs:check
bun run markdownlint
bun run typecheck
bun run test
bun run storybook:build
bun run test:e2e

bun run test:e2e owns a fresh development server with explicit non-production fixture mode. It deterministically verifies the Fixture fallback path and does not attach to an existing server. LOOPWORKS_PORTAL_DATA_MODE=fixtures is ignored in production, where database failures continue to fail closed.

The seeded Postgres browser lane is separate. It requires a local loopworks_e2e database owned by the loopworks role:

createdb --host 127.0.0.1 --username loopworks loopworks_e2e
DATABASE_URL="postgres://loopworks:loopworks@127.0.0.1:5432/loopworks_e2e" \
  bun run test:e2e:seeded

The seeded command refuses production runtimes, non-Postgres URLs, non-loopback hosts, and database names other than loopworks_e2e before it runs migrations. It then runs migrations, resets only the fixed-id demo rows, and requires Live database browser evidence. Migration or seed failures name the failed stage; confirm Postgres is running and that the local role and database exist.

The aggregate command is:

bun run validate

Git Hooks

Loopworks uses pre-k through uvx prek.

bun run precommit:install
bun run precommit:run

The pre-commit hook runs bun run precommit, which mirrors CI validation: Biome format check, Biome lint, agent docs sync, Markdownlint, TypeScript, Vitest, Storybook build, and Playwright.

Planning

  • Agent workflow: AGENTS.md
  • Claude Code shim: CLAUDE.md imports AGENTS.md; run bun run agent-docs:sync after changing agent guides
  • Contributing guide: CONTRIBUTING.MD
  • Product requirements: docs/prd.md
  • Architecture: docs/architecture.md
  • ADR index: docs/adr/README.md
  • Loop manifest: docs/loop-manifest.md
  • Design-system planning: docs/design-system-planning.md
  • Observability: docs/observability.md
  • Personas and test scenarios: docs/personas-and-test-scenarios.md
  • MVP security review: docs/security-review.md

Database Seed Data

After the database bootstrap (bun run db:migrate), seed a demo dataset covering repos, loops, runs, run steps, artifacts, approvals, and Vercel deployment states in every status. DATABASE_URL must explicitly identify a local Postgres database:

bun run db:seed

Seeding is idempotent (upsert by fixed id), so running it again does not duplicate rows. To clear the fixed-id demo rows and reseed from scratch:

bun run db:seed:reset

Reset only deletes the exact rows this script owns, not the whole table, so any other data in those tables is left untouched.

Add -- --dry-run to either command to print the planned row counts without writing. Per ADR 0007, both commands refuse to run when DATABASE_URL is missing or malformed, when NODE_ENV or VERCEL_ENV is production, or when the URL is not Postgres on a loopback host (localhost/127.0.0.1/::1) — Loopworks demo data must never write into a database that isn't explicitly and obviously local.