feat: local tier gateway with PGlite + Gitea-only publishing (#371)
Some checks failed
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/push/publish Pipeline failed

This commit was merged in pull request #371.
This commit is contained in:
2026-04-04 18:39:20 +00:00
parent 86d6c214fe
commit fc7fa11923
29 changed files with 230 additions and 50 deletions

View File

@@ -1,6 +1,11 @@
{
"name": "@mosaic/agent",
"version": "0.0.2",
"repository": {
"type": "git",
"url": "https://git.mosaicstack.dev/mosaic/mosaic-stack.git",
"directory": "packages/agent"
},
"main": "dist/index.js",
"types": "dist/index.d.ts",
"exports": {

View File

@@ -1,6 +1,11 @@
{
"name": "@mosaic/auth",
"version": "0.0.2",
"repository": {
"type": "git",
"url": "https://git.mosaicstack.dev/mosaic/mosaic-stack.git",
"directory": "packages/auth"
},
"type": "module",
"main": "dist/index.js",
"types": "dist/index.d.ts",

View File

@@ -1,6 +1,11 @@
{
"name": "@mosaic/brain",
"version": "0.0.2",
"repository": {
"type": "git",
"url": "https://git.mosaicstack.dev/mosaic/mosaic-stack.git",
"directory": "packages/brain"
},
"main": "dist/index.js",
"types": "dist/index.d.ts",
"exports": {

View File

@@ -1,6 +1,11 @@
{
"name": "@mosaic/cli",
"version": "0.0.10",
"repository": {
"type": "git",
"url": "https://git.mosaicstack.dev/mosaic/mosaic-stack.git",
"directory": "packages/cli"
},
"type": "module",
"main": "dist/index.js",
"types": "dist/index.d.ts",

View File

@@ -1,5 +1,6 @@
import { randomBytes } from 'node:crypto';
import { writeFileSync } from 'node:fs';
import { join } from 'node:path';
import { createInterface } from 'node:readline';
import type { GatewayMeta } from './daemon.js';
import {
@@ -58,6 +59,13 @@ async function doInstall(rl: ReturnType<typeof createInterface>, opts: InstallOp
// Step 2: Collect configuration
console.log('\n─── Gateway Configuration ───\n');
// Tier selection
console.log('Storage tier:');
console.log(' 1. Local (embedded database, no dependencies)');
console.log(' 2. Team (PostgreSQL + Valkey required)');
const tierAnswer = (await prompt(rl, 'Select [1]: ')).trim() || '1';
const tier = tierAnswer === '2' ? 'team' : 'local';
const port =
opts.port !== 4000
? opts.port
@@ -66,12 +74,17 @@ async function doInstall(rl: ReturnType<typeof createInterface>, opts: InstallOp
10,
);
const databaseUrl =
(await prompt(rl, 'DATABASE_URL [postgresql://mosaic:mosaic@localhost:5433/mosaic]: ')) ||
'postgresql://mosaic:mosaic@localhost:5433/mosaic';
let databaseUrl: string | undefined;
let valkeyUrl: string | undefined;
const valkeyUrl =
(await prompt(rl, 'VALKEY_URL [redis://localhost:6380]: ')) || 'redis://localhost:6380';
if (tier === 'team') {
databaseUrl =
(await prompt(rl, 'DATABASE_URL [postgresql://mosaic:mosaic@localhost:5433/mosaic]: ')) ||
'postgresql://mosaic:mosaic@localhost:5433/mosaic';
valkeyUrl =
(await prompt(rl, 'VALKEY_URL [redis://localhost:6380]: ')) || 'redis://localhost:6380';
}
const anthropicKey = await prompt(rl, 'ANTHROPIC_API_KEY (optional, press Enter to skip): ');
@@ -84,8 +97,6 @@ async function doInstall(rl: ReturnType<typeof createInterface>, opts: InstallOp
// Step 3: Write .env
const envLines = [
`GATEWAY_PORT=${port.toString()}`,
`DATABASE_URL=${databaseUrl}`,
`VALKEY_URL=${valkeyUrl}`,
`BETTER_AUTH_SECRET=${authSecret}`,
`BETTER_AUTH_URL=http://${opts.host}:${port.toString()}`,
`GATEWAY_CORS_ORIGIN=${corsOrigin}`,
@@ -93,6 +104,11 @@ async function doInstall(rl: ReturnType<typeof createInterface>, opts: InstallOp
`OTEL_SERVICE_NAME=mosaic-gateway`,
];
if (tier === 'team' && databaseUrl && valkeyUrl) {
envLines.push(`DATABASE_URL=${databaseUrl}`);
envLines.push(`VALKEY_URL=${valkeyUrl}`);
}
if (anthropicKey) {
envLines.push(`ANTHROPIC_API_KEY=${anthropicKey}`);
}
@@ -100,6 +116,26 @@ async function doInstall(rl: ReturnType<typeof createInterface>, opts: InstallOp
writeFileSync(ENV_FILE, envLines.join('\n') + '\n', { mode: 0o600 });
console.log(`\nConfig written to ${ENV_FILE}`);
// Step 3b: Write mosaic.config.json
const mosaicConfig =
tier === 'local'
? {
tier: 'local',
storage: { type: 'sqlite', path: join(GATEWAY_HOME, 'data.db') },
queue: { type: 'local', dataDir: join(GATEWAY_HOME, 'queue') },
memory: { type: 'keyword' },
}
: {
tier: 'team',
storage: { type: 'postgres', url: databaseUrl },
queue: { type: 'bullmq', url: valkeyUrl },
memory: { type: 'pgvector' },
};
const configFile = join(GATEWAY_HOME, 'mosaic.config.json');
writeFileSync(configFile, JSON.stringify(mosaicConfig, null, 2) + '\n', { mode: 0o600 });
console.log(`Config written to ${configFile}`);
// Step 4: Write meta.json
let entryPoint: string;
try {

View File

@@ -1,6 +1,11 @@
{
"name": "@mosaic/config",
"version": "0.0.1",
"repository": {
"type": "git",
"url": "https://git.mosaicstack.dev/mosaic/mosaic-stack.git",
"directory": "packages/config"
},
"type": "module",
"main": "dist/index.js",
"types": "dist/index.d.ts",

View File

@@ -1,6 +1,11 @@
{
"name": "@mosaic/coord",
"version": "0.0.2",
"repository": {
"type": "git",
"url": "https://git.mosaicstack.dev/mosaic/mosaic-stack.git",
"directory": "packages/coord"
},
"main": "dist/index.js",
"types": "dist/index.d.ts",
"exports": {

View File

@@ -1,6 +1,11 @@
{
"name": "@mosaic/db",
"version": "0.0.2",
"repository": {
"type": "git",
"url": "https://git.mosaicstack.dev/mosaic/mosaic-stack.git",
"directory": "packages/db"
},
"type": "module",
"main": "dist/index.js",
"types": "dist/index.d.ts",
@@ -28,6 +33,7 @@
"vitest": "^2.0.0"
},
"dependencies": {
"@electric-sql/pglite": "^0.2.17",
"drizzle-orm": "^0.45.1",
"postgres": "^3.4.8"
},

View File

@@ -0,0 +1,15 @@
import { PGlite } from '@electric-sql/pglite';
import { drizzle } from 'drizzle-orm/pglite';
import * as schema from './schema.js';
import type { DbHandle } from './client.js';
export function createPgliteDb(dataDir: string): DbHandle {
const client = new PGlite(dataDir);
const db = drizzle(client, { schema });
return {
db: db as unknown as DbHandle['db'],
close: async () => {
await client.close();
},
};
}

View File

@@ -1,4 +1,5 @@
export { createDb, type Db, type DbHandle } from './client.js';
export { createPgliteDb } from './client-pglite.js';
export { runMigrations } from './migrate.js';
export * from './schema.js';
export {

View File

@@ -1,6 +1,11 @@
{
"name": "@mosaic/design-tokens",
"version": "0.0.2",
"repository": {
"type": "git",
"url": "https://git.mosaicstack.dev/mosaic/mosaic-stack.git",
"directory": "packages/design-tokens"
},
"type": "module",
"main": "dist/index.js",
"types": "dist/index.d.ts",

View File

@@ -1,6 +1,11 @@
{
"name": "@mosaic/forge",
"version": "0.0.2",
"repository": {
"type": "git",
"url": "https://git.mosaicstack.dev/mosaic/mosaic-stack.git",
"directory": "packages/forge"
},
"type": "module",
"main": "dist/index.js",
"types": "dist/index.d.ts",

View File

@@ -1,6 +1,11 @@
{
"name": "@mosaic/log",
"version": "0.0.2",
"repository": {
"type": "git",
"url": "https://git.mosaicstack.dev/mosaic/mosaic-stack.git",
"directory": "packages/log"
},
"type": "module",
"main": "dist/index.js",
"types": "dist/index.d.ts",

View File

@@ -1,6 +1,11 @@
{
"name": "@mosaic/macp",
"version": "0.0.2",
"repository": {
"type": "git",
"url": "https://git.mosaicstack.dev/mosaic/mosaic-stack.git",
"directory": "packages/macp"
},
"type": "module",
"main": "dist/index.js",
"types": "dist/index.d.ts",

View File

@@ -1,6 +1,11 @@
{
"name": "@mosaic/memory",
"version": "0.0.2",
"repository": {
"type": "git",
"url": "https://git.mosaicstack.dev/mosaic/mosaic-stack.git",
"directory": "packages/memory"
},
"type": "module",
"main": "dist/index.js",
"types": "dist/index.d.ts",

View File

@@ -1,6 +1,11 @@
{
"name": "@mosaic/mosaic",
"version": "0.0.10",
"repository": {
"type": "git",
"url": "https://git.mosaicstack.dev/mosaic/mosaic-stack.git",
"directory": "packages/mosaic"
},
"description": "Mosaic agent framework — installation wizard and meta package",
"type": "module",
"main": "dist/index.js",
@@ -27,7 +32,7 @@
"@mosaic/quality-rails": "workspace:*",
"@mosaic/types": "workspace:*",
"@clack/prompts": "^0.9.1",
"commander": "^12.1.0",
"commander": "^13.0.0",
"picocolors": "^1.1.1",
"yaml": "^2.6.1",
"zod": "^3.23.8"

View File

@@ -1,6 +1,11 @@
{
"name": "@mosaic/prdy",
"version": "0.0.2",
"repository": {
"type": "git",
"url": "https://git.mosaicstack.dev/mosaic/mosaic-stack.git",
"directory": "packages/prdy"
},
"main": "dist/index.js",
"types": "dist/index.d.ts",
"exports": {
@@ -17,7 +22,7 @@
},
"dependencies": {
"@clack/prompts": "^0.9.0",
"commander": "^12.0.0",
"commander": "^13.0.0",
"js-yaml": "^4.1.0",
"zod": "^3.22.0"
},

View File

@@ -1,6 +1,11 @@
{
"name": "@mosaic/quality-rails",
"version": "0.0.3",
"repository": {
"type": "git",
"url": "https://git.mosaicstack.dev/mosaic/mosaic-stack.git",
"directory": "packages/quality-rails"
},
"type": "module",
"main": "dist/index.js",
"types": "dist/index.d.ts",

View File

@@ -1,6 +1,11 @@
{
"name": "@mosaic/queue",
"version": "0.0.2",
"repository": {
"type": "git",
"url": "https://git.mosaicstack.dev/mosaic/mosaic-stack.git",
"directory": "packages/queue"
},
"main": "dist/index.js",
"types": "dist/index.d.ts",
"exports": {

View File

@@ -1,6 +1,11 @@
{
"name": "@mosaic/storage",
"version": "0.0.2",
"repository": {
"type": "git",
"url": "https://git.mosaicstack.dev/mosaic/mosaic-stack.git",
"directory": "packages/storage"
},
"main": "dist/index.js",
"types": "dist/index.d.ts",
"exports": {

View File

@@ -1,6 +1,11 @@
{
"name": "@mosaic/types",
"version": "0.0.2",
"repository": {
"type": "git",
"url": "https://git.mosaicstack.dev/mosaic/mosaic-stack.git",
"directory": "packages/types"
},
"main": "dist/index.js",
"types": "dist/index.d.ts",
"exports": {