Skip to content

chore: add one-command local-dev sign-in (pnpm dev:login)#1419

Merged
eskp merged 6 commits into
stagingfrom
chore/local-dev-login
May 30, 2026
Merged

chore: add one-command local-dev sign-in (pnpm dev:login)#1419
eskp merged 6 commits into
stagingfrom
chore/local-dev-login

Conversation

@eskp
Copy link
Copy Markdown

@eskp eskp commented May 30, 2026

Summary

  • Adds pnpm dev:login: one command takes a fresh worktree to a signed-in browser, skipping the signup -> OTP -> MFA -> TOTP UI loop.
  • Bootstraps the local DB (idempotent), mints a Better Auth session via the same signSessionCookieValue / hashSessionToken helpers the production OAuth-MFA finalize path uses (imported, not modified), ensures a dev server is serving localhost:3000 (reuses a running one or spawns pnpm dev detached and waits for readiness), then launches a dedicated detached Chromium profile already signed in.
  • Lower-level entry points: pnpm dev:bootstrap (DB setup only) and KEEPERHUB_DEV_MINT=1 pnpm dev:mint-cookie <email> (cookie only, no browser).
  • Replaces the old curl + SQL create-local-dev command with the dev-login command + create-local-dev skill.

Safety boundaries

  • All three scripts refuse to run unless DATABASE_URL host is local (localhost/127.0.0.1/::1/db/postgres); dev:mint-cookie additionally requires KEEPERHUB_DEV_MINT=1.
  • No production auth, API route, or runtime code is modified. lib/auth.ts and lib/auth-session-token-hash.ts are imported only.
  • Minted cookie (.claude/.dev-session-cookie-LOCAL), Chromium profile (.claude/.dev-chrome-profile/), and server log (.claude/.dev-server-LOCAL.log) are gitignored.

Test plan

  • pnpm dev:login from a fresh worktree opens a signed-in Chromium at localhost:3000 (verified end-to-end).
  • Cold-start path: with no server running, dev:login starts pnpm dev, waits for readiness, then opens the signed-in window (verified end-to-end).
  • pnpm type-check clean.
  • pnpm check clean for changed files.
  • /dev-login slash command available after merge + pull (to verify next session).

No unit tests added: this is developer tooling (a Playwright-launching orchestrator + DB seed); verification is the end-to-end run plus the lint/type-check gates.

eskp added 4 commits May 30, 2026 17:14
Add a single-command local-dev sign-in that takes a fresh worktree to a
signed-in browser without the signup -> OTP -> MFA -> TOTP UI loop.

pnpm dev:login:
- bootstraps the local DB (idempotent): journal backfill when needed,
  db:migrate, seeds persistent e2e users plus a dev user/org, pre-trusts
  127.0.0.1 + ::1, marks the dev user twoFactorEnabled, binds the local
  kh CLI token, and upserts 8 workflow fixtures
- mints a Better Auth session using the same signSessionCookieValue /
  hashSessionToken helpers the production OAuth-MFA finalize path uses
  (imported, not modified)
- ensures a dev server is serving localhost:3000: reuses a running one
  or spawns pnpm dev detached and waits for readiness
- seeds the cookie into a dedicated Playwright Chromium profile and
  launches it detached

All scripts refuse to run unless DATABASE_URL host is local; dev:mint-cookie
additionally requires KEEPERHUB_DEV_MINT=1. No production auth, API route,
or runtime code is modified. The minted cookie file, Chromium profile, and
server log are gitignored.

Replaces the old curl + SQL create-local-dev command. Lower-level entry
points remain: pnpm dev:bootstrap, pnpm dev:mint-cookie.
Address non-blocking findings from PR review:

- dev-login.ts: close the dev-server log file descriptor after spawning
  the detached child, so the parent does not leak it for the rest of its
  lifetime. The child keeps its own dup'd descriptor.
- dev-login.ts / dev-login-browser.ts: pass the signed session cookie to
  the detached browser via the KEEPERHUB_DEV_COOKIE env var instead of
  argv. Process argv is world-readable (ps, /proc/<pid>/cmdline); the
  environ is owner-only. URL and profile dir stay positional (not secret).
- dev-mint-session.ts: order the active-org fallback query by member
  createdAt so a multi-org seeded user resolves to a deterministic org
  instead of an arbitrary first row.
Follow-up to the local-dev sign-in hardening: order the active-org
fallback query in dev-mint-session by member createdAt so a multi-org
seeded user resolves to a deterministic org instead of an arbitrary
first row.
dev-bootstrap.ts imports seedPersistentTestUsers from tests/, which
.dockerignore strips from the build context, so next build's type check
failed to resolve the module. These scripts are dev:login-only and never
run in production, so exclude them from the image entirely.
next build type-checks scripts/ via the **/*.ts include. dev-bootstrap.ts
imports a helper from tests/, which is absent in the Docker image, so the
build's type check could not resolve the module. These are tsx-run
dev:login-only scripts; exclude them from type checking.
@eskp eskp merged commit 8c84eaf into staging May 30, 2026
41 checks passed
@eskp eskp deleted the chore/local-dev-login branch May 30, 2026 10:56
@github-actions
Copy link
Copy Markdown

🧹 PR Environment Cleaned Up

The PR environment has been successfully deleted.

Deleted Resources:

  • Namespace: pr-1419
  • All Helm releases (Keeperhub, Scheduler, Event services)
  • PostgreSQL Database (including data)
  • LocalStack, Redis
  • All associated secrets and configs

All resources have been cleaned up and will no longer incur costs.

@github-actions
Copy link
Copy Markdown

ℹ️ No PR Environment to Clean Up

No PR environment was found for this PR. This is expected if:

  • The PR never had the deploy-pr-environment label
  • The environment was already cleaned up
  • The deployment never completed successfully

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant