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

+52
View File
@@ -0,0 +1,52 @@
import { ProjectsService } from "@primora/api-client";
import { loadConfig } from "../config.js";
import { configureClient, requireAuth, requireOrg } from "../http.js";
import { isJson, printJson, printTable, success } from "../out.js";
interface ListOptions {
org?: string;
q?: string;
json?: boolean;
}
export async function cmdProjectsList(options: ListOptions): Promise<void> {
const cfg = loadConfig();
requireAuth(cfg);
configureClient(cfg);
const organizationId = requireOrg(cfg, options.org);
const { items } = await ProjectsService.listProjects({
organizationId,
q: options.q || undefined,
});
if (isJson(options)) {
printJson(items);
return;
}
printTable(
["ID", "SLUG", "NAME", "ROLE"],
items.map((pr) => [pr.id, pr.slug, pr.name, pr.membership_role ?? "—"]),
);
}
export async function cmdProjectsCreate(
name: string,
options: { org?: string; slug?: string; description?: string; json?: boolean },
): Promise<void> {
const cfg = loadConfig();
requireAuth(cfg);
configureClient(cfg);
const organizationId = requireOrg(cfg, options.org);
const slug = options.slug ?? name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
const project = await ProjectsService.createProject({
organizationId,
requestBody: { name, slug, description: options.description },
});
if (isJson(options)) {
printJson(project);
return;
}
success(`Project "${project.name}" created (${project.slug})`);
}