feat: ship phase 1 surface area (v0.2.0)

- primora CLI + @primora/mcp server over generated client
- auth users admin panel, mobile bottom nav
- release workflow: GHCR images, compiled binaries, npm tarballs
- fix gzip Content-Length truncation, nginx upstream re-resolution

Authored By: TDvorak <[email protected]>

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
Tomas DvorakandDevin committed 2026-09-16 14:04:43 +02:00
1 parent f77823ad90
commit 420502eec1
90 files changed
+9172 -9718

No files matched your search

+2
View File
@@ -3,7 +3,9 @@ WORKDIR /workspace
COPY package.json package-lock.json tsconfig.base.json ./
COPY apps/auth/package.json ./apps/auth/package.json
COPY apps/cli/package.json ./apps/cli/package.json
COPY apps/frontend/package.json ./apps/frontend/package.json
COPY apps/mcp/package.json ./apps/mcp/package.json
COPY packages/api-client/package.json ./packages/api-client/package.json
COPY packages/shared-types/package.json ./packages/shared-types/package.json
+1 -1
View File
@@ -7,7 +7,7 @@
"build": "tsc -p tsconfig.json",
"dev": "tsx watch src/index.ts",
"start": "node dist/index.js",
"test": "vitest run"
"test": "vitest run --passWithNoTests"
},
"dependencies": {
"@hono/node-server": "^1.19.4",
+2 -1
View File
@@ -5,7 +5,7 @@ import { requestId } from "hono/request-id";
import { HTTPException } from "hono/http-exception";
import { createClient } from "redis";
import { auth, authPool, runAuthMigrations } from "./lib/auth.js";
import { auth, authPool, promoteAdminEmails, runAuthMigrations } from "./lib/auth.js";
import { env } from "./lib/env.js";
const redisClient = createClient({
@@ -19,6 +19,7 @@ try {
}
await retry("auth_migrations", runAuthMigrations);
await promoteAdminEmails();
const app = new Hono();
+12 -1
View File
@@ -1,5 +1,5 @@
import { betterAuth } from "better-auth";
import { jwt } from "better-auth/plugins";
import { admin, jwt } from "better-auth/plugins";
import { getMigrations } from "better-auth/db/migration";
import { Pool } from "pg";
@@ -95,6 +95,7 @@ export const auth = betterAuth({
},
},
}),
admin(),
],
});
@@ -103,3 +104,13 @@ export async function runAuthMigrations() {
await migrations.runMigrations();
}
/** Bootstrap admins by email — run after migrations so the role column exists. */
export async function promoteAdminEmails() {
const emails = (env.AUTH_ADMIN_EMAILS ?? "")
.split(",")
.map((email) => email.trim().toLowerCase())
.filter(Boolean);
if (emails.length === 0) return;
await authPool.query(`update "user" set role = 'admin' where lower(email) = any($1)`, [emails]);
}
+1
View File
@@ -27,6 +27,7 @@ const envSchema = z.object({
MICROSOFT_CLIENT_ID: z.string().optional(),
MICROSOFT_CLIENT_SECRET: z.string().optional(),
MICROSOFT_TENANT_ID: z.string().optional(),
AUTH_ADMIN_EMAILS: z.string().optional(),
});
const parsed = envSchema.safeParse(process.env);