Move src/ → apps/server/ and packages/web/ → apps/web/ to adopt standard monorepo conventions (apps/ for runnable apps, packages/ for reusable libraries). Update all config files, shared package imports, test fixtures, and documentation to reflect new paths. Key fixes: - Update workspace config to ["apps/*", "packages/*"] - Update tsconfig.json rootDir/include for apps/server/ - Add apps/web/** to vitest exclude list - Update drizzle.config.ts schema path - Fix ensure-schema.ts migration path detection (3 levels up in dev, 2 levels up in dist) - Fix tests/integration/cli-server.test.ts import paths - Update packages/shared imports to apps/server/ paths - Update all docs/ files with new paths
111 lines
3.4 KiB
TypeScript
111 lines
3.4 KiB
TypeScript
/**
|
|
* System Router — health, status, systemHealthCheck
|
|
*/
|
|
|
|
import { z } from 'zod';
|
|
import { join } from 'node:path';
|
|
import { access } from 'node:fs/promises';
|
|
import type { ProcedureBuilder } from '../trpc.js';
|
|
import { requireAccountRepository, requireProjectRepository } from './_helpers.js';
|
|
import { checkAccountHealth } from '../../agent/accounts/usage.js';
|
|
import { getProjectCloneDir } from '../../git/project-clones.js';
|
|
|
|
export const healthResponseSchema = z.object({
|
|
status: z.literal('ok'),
|
|
uptime: z.number().int().nonnegative(),
|
|
processCount: z.number().int().nonnegative(),
|
|
});
|
|
|
|
export type HealthResponse = z.infer<typeof healthResponseSchema>;
|
|
|
|
export const processInfoSchema = z.object({
|
|
id: z.string(),
|
|
pid: z.number().int().positive(),
|
|
command: z.string(),
|
|
status: z.string(),
|
|
startedAt: z.string(),
|
|
});
|
|
|
|
export type ProcessInfo = z.infer<typeof processInfoSchema>;
|
|
|
|
export const statusResponseSchema = z.object({
|
|
server: z.object({
|
|
startedAt: z.string(),
|
|
uptime: z.number().int().nonnegative(),
|
|
pid: z.number().int().positive(),
|
|
}),
|
|
processes: z.array(processInfoSchema),
|
|
});
|
|
|
|
export type StatusResponse = z.infer<typeof statusResponseSchema>;
|
|
|
|
export function systemProcedures(publicProcedure: ProcedureBuilder) {
|
|
return {
|
|
health: publicProcedure
|
|
.output(healthResponseSchema)
|
|
.query(({ ctx }): HealthResponse => {
|
|
const uptime = ctx.serverStartedAt
|
|
? Math.floor((Date.now() - ctx.serverStartedAt.getTime()) / 1000)
|
|
: 0;
|
|
|
|
return {
|
|
status: 'ok',
|
|
uptime,
|
|
processCount: ctx.processCount,
|
|
};
|
|
}),
|
|
|
|
status: publicProcedure
|
|
.output(statusResponseSchema)
|
|
.query(({ ctx }): StatusResponse => {
|
|
const uptime = ctx.serverStartedAt
|
|
? Math.floor((Date.now() - ctx.serverStartedAt.getTime()) / 1000)
|
|
: 0;
|
|
|
|
return {
|
|
server: {
|
|
startedAt: ctx.serverStartedAt?.toISOString() ?? '',
|
|
uptime,
|
|
pid: process.pid,
|
|
},
|
|
processes: [],
|
|
};
|
|
}),
|
|
|
|
systemHealthCheck: publicProcedure
|
|
.query(async ({ ctx }) => {
|
|
const uptime = ctx.serverStartedAt
|
|
? Math.floor((Date.now() - ctx.serverStartedAt.getTime()) / 1000)
|
|
: 0;
|
|
|
|
const accountRepo = requireAccountRepository(ctx);
|
|
const allAccounts = await accountRepo.findAll();
|
|
const allAgents = ctx.agentManager ? await ctx.agentManager.list() : [];
|
|
|
|
const accounts = await Promise.all(
|
|
allAccounts.map(account => checkAccountHealth(account, allAgents, ctx.credentialManager, ctx.workspaceRoot ?? undefined))
|
|
);
|
|
|
|
const projectRepo = requireProjectRepository(ctx);
|
|
const allProjects = await projectRepo.findAll();
|
|
|
|
const projects = await Promise.all(
|
|
allProjects.map(async project => {
|
|
let repoExists = false;
|
|
if (ctx.workspaceRoot) {
|
|
const clonePath = join(ctx.workspaceRoot, getProjectCloneDir(project.name, project.id));
|
|
try { await access(clonePath); repoExists = true; } catch { repoExists = false; }
|
|
}
|
|
return { id: project.id, name: project.name, url: project.url, repoExists };
|
|
})
|
|
);
|
|
|
|
return {
|
|
server: { status: 'ok' as const, uptime, startedAt: ctx.serverStartedAt?.toISOString() ?? null },
|
|
accounts,
|
|
projects,
|
|
};
|
|
}),
|
|
};
|
|
}
|