feat(relay): Phase1 waves A2-E — server entry, shared-store data plane, agent runtime, deploy artifacts
RELAY-PHASE1 Wave A2/B/C/D/E (12-agent workflow, all tsc-clean, 314/314 tests pass): - A2: control-plane server.ts entry + boot/redis.ts revocation-bus wiring + start script. - B1: relay-run shared-store EnforceDeps (relay-auth ports over the SAME Postgres+Redis as P3). - B2: registry-backed MtlsVerifier (verifyAgentCert, fail-closed, INV14). - B3: store-backed RouteResolver (subdomain->hostId). - B4: Redis relay:revocations subscriber -> tunnel teardown (INV12). - B5: main-phase1.ts production entry (public bind, real TLS, async-mTLS prefetch bridge) + staging /auth/mint. - B6 (PARTIAL): relay-web operator login + browser DPoP; proof offered via term.dpop.<b64u> subprotocol. - C: agent dist/cli.js build (esbuild) + runTunnel run-loop + CliDeps. - D1: same-origin static serve of relay-web/public from the browser WSS. - E: systemd units + gen-ca/gen-capability-key/issue-tls-cert scripts + deploy/RUNBOOK.md. Adversarial review: all hard invariants PASS. Follow-ups (B7): close DPoP-subprotocol read on browser-server (blocks browser connect); rate-limit /auth/mint (F1); wire activeSessionCount (F2); scrub error logs (F5). Excludes unrelated public/style.css (concurrent iOS job).
This commit is contained in:
30
agent/src/main.ts
Normal file
30
agent/src/main.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* CLI bootstrap — PLAN_RELAY_PHASE1 C2. The `dist/cli.js` entrypoint (the `#!/usr/bin/env node`
|
||||
* shebang is prepended at build time via esbuild `--banner`, NOT here). Reads argv, builds the
|
||||
* real CliDeps, dispatches through `runCli`, and maps any error to a clean stderr line + exit code
|
||||
* (usage errors ⇒ 2, everything else ⇒ 1) so no invocation ever crashes with a raw stack trace.
|
||||
*/
|
||||
import { parseArgs, runCli, CliUsageError } from './cli.js'
|
||||
import { createCliDeps } from './cli/deps.js'
|
||||
|
||||
async function main(): Promise<number> {
|
||||
const argv = process.argv.slice(2)
|
||||
const deps = createCliDeps()
|
||||
try {
|
||||
return await runCli(parseArgs(argv), deps)
|
||||
} catch (err) {
|
||||
const message = err instanceof Error ? err.message : String(err)
|
||||
process.stderr.write(`web-terminal-agent: ${message}\n`)
|
||||
return err instanceof CliUsageError ? 2 : 1
|
||||
}
|
||||
}
|
||||
|
||||
main()
|
||||
.then((code) => {
|
||||
process.exitCode = code
|
||||
})
|
||||
.catch((err: unknown) => {
|
||||
const message = err instanceof Error ? err.message : String(err)
|
||||
process.stderr.write(`web-terminal-agent: fatal ${message}\n`)
|
||||
process.exitCode = 1
|
||||
})
|
||||
Reference in New Issue
Block a user